Search code examples
c#win-universal-apptemplate10

How to show a Modal Dialog and Cancel Navigation in OnNavigatingFromAsync


When using Template 10 you are given the opportunity to have a page's ViewModel cancel navigating away from the page by overriding the INavigable method OnNavigatingFromAsync and setting args.Cancel to true, like so:

public override Task OnNavigatingFromAsync(NavigatingEventArgs args)
{
    // some logic to determine if navigation should be canceled...
    args.Cancel = true;
    return Task.CompletedTask;
}

This works just fine, however if I wanted to show a modal dialog to the user, (explaining why the navigation is being cancelled), I would modify the method to be:

public async override Task OnNavigatingFromAsync(NavigatingEventArgs args)
{
    args.Cancel = true;
    ContentDialog dlg = new ContentDialog()
    {
        Title = "Bad",
        Content = "no no no!",
        PrimaryButtonText = "OK",
        SecondaryButtonText = "NO"
    };
    await dlg.ShowAsync();           
}

This will show the dialog, however the navigation is not cancelled. It's like T10 is ignoring args.Cancel = true; being set.

Am I doing something wrong here? I just want to show the dialog and then prevent navigation..


Solution

  • I am tried your Modal on Template 10 (1.1.4) on the Hamburger Sample and it works perfectly.

    For me i think your error is on the method "OnNavigatingFromAsync", it looks like it is missing "return Task.CompletedTask" at the end.

    For me this code stops the app from going back when I click on the back key in the app:

     public override Task OnNavigatingFromAsync(NavigatingEventArgs args)
            {
                args.Cancel = true;
    
                ContentDialog dlg = new ContentDialog()
                {
                    Title = "Bad",
                    Content = "no no no!",
                    PrimaryButtonText = "OK",
                    SecondaryButtonText = "NO"
                };
                dlg.ShowAsync();
    
                return Task.CompletedTask;
            }