Everything about implementing Back Navigation In UWP App

This article will cover everything you need to know about implementing back navigation in a UWP app. It includes Windows phone hardware back button handling.

While I was migrating my App to Windows 10 UWP, I faced some issues implementing back navigation and related things. I've found a few solutions with different implementation. I'm combining all those things here with the proper code. So, this will be a complete solution to implement back navigation and related concepts in your UWP App.
 
This article is geared for app development in UWP Windows 10 with C# and XAML. 
 
While coding a UWP app, you need to take care of two platforms; mainly, Windows Phone and other Windows devices (including tablet and desktop/surface hub). While in some devices you'll get a hardwared back button for backward navigation so you don't need to include UI for the back button in your app, whereas in the desktop you need to include a Back Button in your application's UI.
 
There are two ways to manage backward navigation in UWP
  1. Implement Windows.UI.Core.SystemNavigationManager API 
  2. Implement custom logic with Back Button in Application's UI
Let's elaborate this in detail with code examples.

Implementing SystemNavigationMnager

There are two benefits of using SystemNavigationManager.
  • If the App is running on the device which doesn't have hardware back button, it'll show the back button onthe application's window header.
  • You don't need to import any external SDK to do this.

 
To make that back button visible on the specific page and handle the click event of that back button, write the following code in the page's constructor or in Loaded event of that page.
  1. SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;  
  2. SystemNavigationManager.GetForCurrentView().BackRequested += (s, e) =>  
  3. {  
  4.     // Handle the Back pressed  
  5. };  
The real essence of using this technique is to implement SystemNavigationManager in a way so that you don't need to write this code in every page but you can manage it throughout the App.
 
To do that, you need to make some changes in App.xaml.cs file of your App.

You need to add some code to your OnLaunched event handler as below. The code to be added is highlighted in red ink.
  1. protected override void OnLaunched(LaunchActivatedEventArgs e)  
  2. {  
  3.   
  4.     Frame rootFrame = Window.Current.Content as Frame;  
  5.   
  6.     // Do not repeat app initialization when the Window already has content,  
  7.     // just ensure that the window is active  
  8.     if (rootFrame == null)  
  9.     {  
  10.         // Create a Frame to act as the navigation context and navigate to the first page  
  11.         rootFrame = new Frame();  
  12.   
  13.         rootFrame.NavigationFailed += OnNavigationFailed;  
  14.         rootFrame.Navigated += RootFrame_Navigated;  
  15.   
  16.         if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)  
  17.         {  
  18.             //TODO: Load state from previously suspended application  
  19.         }  
  20.   
  21.         // Place the frame in the current Window  
  22.         Window.Current.Content = rootFrame;  
  23.   
  24.         // Register a handler for BackRequested events and set the  
  25.         // visibility of the Back button  
  26.         SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;  
  27.   
  28.         SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =  
  29.             rootFrame.CanGoBack ?  
  30.             AppViewBackButtonVisibility.Visible :  
  31.             AppViewBackButtonVisibility.Collapsed;  
  32.   
  33.     }  
  34.   
  35.     if (rootFrame.Content == null)  
  36.     {  
  37.         // When the navigation stack isn't restored navigate to the first page,  
  38.         // configuring the new page by passing required information as a navigation  
  39.         // parameter  
  40.         rootFrame.Navigate(typeof(Page1), e.Arguments);  
  41.     }  
  42.     // Ensure the current window is active  
  43.     Window.Current.Activate();  
  44. }  
Now, add two event handlers in App.xaml.cs file as below which we've declared in above code.
  1. private void RootFrame_Navigated(object sender, NavigationEventArgs e)  
  2. {  
  3.     // Each time a navigation event occurs, update the Back button's visibility  
  4.     SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =  
  5.         ((Frame)sender).CanGoBack ?  
  6.         AppViewBackButtonVisibility.Visible :  
  7.         AppViewBackButtonVisibility.Collapsed;  
  8. }  
  9.   
  10. private void OnBackRequested(object sender, BackRequestedEventArgs e)  
  11. {  
  12.     Frame rootFrame = Window.Current.Content as Frame;  
  13.   
  14.     if (rootFrame.CanGoBack)  
  15.     {  
  16.         e.Handled = true;  
  17.         rootFrame.GoBack();  
  18.     }  
  19. }  
That's it.

By adding above code in App.xaml.cs you'll get a fully functional Back Button throughout your App.

Note: You can find more detail about the above solution from the following blog.

Implement your own logic with Back Button in the App UI

While implementing custom logic, the important thing to take care is of showing the back button on Windows Desktopm but hiding it while in the Windows phone. For that we need to detect which device the app is running on. To detect that we have two options.
  • Use VisualStateManager in XAML 
  • Detecting through backend code 
Sometimes using VisualStateManager to detect whether the app is running on the Windows phone or desktop can cause inaccuracy because the user can resize the App window in Desktop mode. Though the code should look like this:
  1. <VisualStateManager.VisualStateGroups>  
  2.     <VisualStateGroup>  
  3.         <VisualState x:Name="visualStateDesktop">  
  4.             <VisualState.StateTriggers>  
  5.                 <AdaptiveTrigger MinWindowWidth="700" />  
  6.             </VisualState.StateTriggers>  
  7.             <VisualState.Setters>  
  8.                 <Setter Target="btnBack.Visibility" Value="Visible" />  
  9.             </VisualState.Setters>  
  10.         </VisualState>  
  11.   
  12.         <VisualState x:Name="visualStateMobile">  
  13.             <VisualState.StateTriggers>  
  14.                 <AdaptiveTrigger MinWindowWidth="0" />  
  15.             </VisualState.StateTriggers>  
  16.             <VisualState.Setters>  
  17.                 <Setter Target="btnBack.Visibility" Value="Collapsed" />  
  18.             </VisualState.Setters>  
  19.         </VisualState>  
  20.     </VisualStateGroup>  
  21. </VisualStateManager.VisualStateGroups>  
Here btnBack is the name of back button which we've added as in the following screenshot:
 
 
 Now, to detect the platform (whether Windows phone or desktop) by C# code we just need to add one method in App.xaml.cs page.
  1. public static Platform DetectPlatform()  
  2. {  
  3.     bool isHardwareButtonsAPIPresent = ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");  
  4.   
  5.     if (isHardwareButtonsAPIPresent)  
  6.     {  
  7.         return Platform.WindowsPhone;  
  8.     }  
  9.     else  
  10.     {  
  11.         return Platform.Windows;  
  12.     }  
  13. }  
This method will return enum value of Windows.Foundation.Metadata.Platform. We can use this method something like this.
  1. if (App.DetectPlatform() == Platform.WindowsPhone)  
  2. {  
  3.     HardwareButtons.BackPressed += new EventHandler<BackPressedEventArgs>((s, a) =>  
  4.     {  
  5.         if (frameContent.CanGoBack)  
  6.         {  
  7.             frameContent.GoBack();  
  8.             a.Handled = true;  
  9.         }  
  10.     });  
  11. }  
Using this method is important here because Windows.Phone.UI.Input.HardwareButtons class will only available through Windows Mobile Extension for the UWP in reference manager.
 
 

So while runningthe app on the Windows desktop an exception will fire while executing HardwareButtons.BackPressed line of code if there will not be any condition to check the current platform.

Conclusion 

So in this article we've covered the following topics:
  • Back navigation
  • Using Default API for Back Navigation (SystemNavigationmanager)
  • Managing Back Button visibility on Windows desktop through VisualStateManager
  • Handling hardware BackButton in Windows phone
  • Detecting platform whether Windows Phone or Windows
I hope this article will be helpful. If you find anything to include or change, please comment.
 
Read more articles on Universal Windows Apps: