Blog

Handling the Back Button in Windows 10 UWP Apps

The cool thing about Universal Windows Platform (UWP) apps is that they run on an assortment of devices, from PCs, tablets, and phones to (soon) Xboxes and HoloLens, among others. Personally, I can’t wait to see some of the apps I’ve written light up on my kids’ Xbox. They’ll think I’m a hero (“my dad writes Xbox apps!”) even though I’m not.

But as every hero knows, with great power comes great responsibility. One of the issues you’ll run into when writing a UWP app is how to handle the Back button. Windows phones have Back buttons, but other devices don’t. One way to handle the Back button on phones is to add a reference to Microsoft’s Mobile Extension SDK and write adaptive code that responds to HardwareButtons.BackPressed events, as I wrote about in a previous post. Of course, that doesn’t solve the problem of allowing users to navigate backward on devices that lack Back buttons. Which is why Microsoft introduced the Windows.UI.Core.SystemNavigationManager class. SystemNavigationManager does two important things for you:

  • Upon request, it displays a software Back button when your app is running on a device without a Back button
  • It allows you to handle clicks of the Back button (software or hardware) without adding extension SDKs and without writing adaptive code

Here’s what Contoso Cookbook looks like on a PC with a SystemNavigationManager-provided Back button:

Making the Back button appear requires just one line of code:

SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;

Responding to clicks of the Back button is a simple matter of wiring up a handler for SystemNavigationManager.BackRequested events:

SystemNavigationManager.GetForCurrentView().BackRequested += (s, e) =>
{
    // TODO: Go back to the previous page
};

The beauty of it is that this code works without change on phones and other devices. SystemNavigationManager is smart enough not to display a software Back button on devices that have Back buttons, and to fire BackRequested events when the user clicks the software Back button provided by SystemNavigationManager or taps the hardware Back button on a phone.

So far, so good. But here’s where it gets interesting. How do you leverage SystemNavigationManager in a multipage app without adding SystemNavigationManager code to every page? Is there a way, for example, to centralize the Back-button code so that it “just works” independent of how many pages the app has or the content of those pages?

The answer is a resounding yes. In fact, there’s a pattern I use in the UWP apps I write that isolates all the SystemNavigationManager code in App.xaml.cs and works exactly as you’d expect it to. The Back button appears whenever the backstack contains a page to go back to, and disappears when it does not. All you have to do is add a few lines of code to the code already in App.xaml.cs. Here’s a stock App.xaml.cs file created by Visual Studio (minus some of the extraneous stuff VS includes), with the code added to handle the Back button highlighted in red:

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;

        // Do not repeat app initialization when the Window already has content,
        // just ensure that the window is active
        if (rootFrame == null)
        {
            // Create a Frame to act as the navigation context and navigate to the first page
            rootFrame = new Frame();

            rootFrame.NavigationFailed += OnNavigationFailed;
            rootFrame.Navigated += OnNavigated;

            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                // TODO: Load state from previously suspended application
            }

            // Place the frame in the current Window
            Window.Current.Content = rootFrame;

            // Register a handler for BackRequested events and set the
            // visibility of the Back button
            SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;

            SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
                rootFrame.CanGoBack  ?
                AppViewBackButtonVisibility.Visible :
                AppViewBackButtonVisibility.Collapsed;
        }

        if (rootFrame.Content == null)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }

        // Ensure the current window is active
        Window.Current.Activate();
    }

    void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
    {
        throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
    }

    private void OnNavigated(object sender, NavigationEventArgs e)
    {
        // Each time a navigation event occurs, update the Back button's visibility
        SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
            ((Frame)sender).CanGoBack ?
            AppViewBackButtonVisibility.Visible :
            AppViewBackButtonVisibility.Collapsed;
    }

    private void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        // TODO: Save application state and stop any background activity
        deferral.Complete();
    }

    private void OnBackRequested(object sender, BackRequestedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;

        if (rootFrame.CanGoBack)
        {
            e.Handled = true;
            rootFrame.GoBack();
        }
    }
}

Plug these lines into App.xaml.cs and you, too, can achieve Back-button bliss in UWP apps!

Jeff Prosise

View Comments

  • One question I have on this implementation... how does the Windows Mobile form factor deal with the Back Button being pressed on the *top level* page? I.e. where it should *normally* exit the app. I've seen some weirdness in this area after implementing this code... Full disclosure, I'm using Template10 from Jerry Nixon (https://github.com/Windows-XAML/Template10) which wraps this behavior.

    • It ties into the OS's back button. The one next to the start button that's a hardware button on some phones. The interesting part is that there is no visual indication of what will happen when you press that button.

  • One question I have on this implementation... how does the Windows Mobile form factor deal with the Back Button being pressed on the *top level* page? I.e. where it should *normally* exit the app. I've seen some weirdness in this area after implementing this code... Full disclosure, I'm using Template10 from Jerry Nixon (https://github.com/Windows-XAML/Template10) which wraps this behavior.

  • Thanks Wintellect for such a nice blog.This helped me alot.
    But I need restrict the back button functionality to goback again to Login page after the user login into my app. How to handle this?

    • When navigating away from Login page remove its page stack entry.
      eg : this.Frame.BackStack.Remove(this.Frame.BackStack.LastOrDefault());

      • Where I need to put this?
        I tried in different location. Can u tell me exactly, please?
        Edit: Thank u, I forget OnNavigatedFrom event !

      • Add these line in your login page onnavigating from method.
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
        this.Frame.BackStack.Remove(this.Frame.BackStack.LastOrDefault());
        }

  • Thanks Wintellect for such a nice blog.This helped me alot.
    But I need restrict the back button functionality to goback again to Login page after the user login into my app. How to handle this?

  • Don't forget to remove handler when navigate from the previous page ! Without this, SystemNavigationManager will go back many times

  • This is great, EXCEPT when I use this in conjunction with a splitview menu, when navigating back the SELECTED item in the splitview doesn't change to match the page I have gone back to. Any solution for this?

  • This is great, EXCEPT when I use this in conjunction with a splitview menu, when navigating back the SELECTED item in the splitview doesn't change to match the page I have gone back to. Any solution for this?

    • Hi, Do you find the solution of your problem?, I actually have the same problem and i dont know how to deal with it.

Recent Posts

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

6 days ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago

Mastering Compliance: The Definitive Guide to Managed Compliance Services

In the intricate landscape of modern business, compliance is both a cornerstone of operational integrity…

2 months ago