Search code examples
c#win-universal-appuwpwindows-10-mobilemobile-development

(UWP) Hardware Back Press work correctly in mobile but error with PC


In my UWP app when i click on mobile back button app get close, so add this code in app.xaml.cs

 private async void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
       {

           e.Handled = true;
           Frame rootFrame = Window.Current.Content as Frame;
           if (rootFrame.CanGoBack && rootFrame != null)
           {

               rootFrame.GoBack();
           }
           else
           {
               var msg = new MessageDialog("Confirm Close! \nOr Press Refresh Button to Go Back");
               var okBtn = new UICommand("OK");
               var cancelBtn = new UICommand("Cancel");
               msg.Commands.Add(okBtn);
               msg.Commands.Add(cancelBtn);
               IUICommand result = await msg.ShowAsync();

               if (result != null && result.Label == "OK")
               {
                   Application.Current.Exit();
               }
           }
       }

and

    public App()
    {            
        this.InitializeComponent();
        this.Suspending += OnSuspending;

    /*  Because of this line my app work on mobile great but when
        when i debug on pc it through exception "show in image" */
        HardwareButtons.BackPressed += HardwareButtons_BackPressed;
    }

After Done all this code when i debug app on phone, app successfully run - Mobile Debuging:

enter image description here

But when debug in pc with same code, it show this error- PC Debuging:

enter image description here

when i remove HardwareButtons.BackPressed += HardwareButtons_BackPressed; then issue with pc debugging resolved but in mobile debuging back button again is not work.


Solution

  • The reason is that HardwareButtons API is not the universal solution for handling the back button. This API is available only in the Mobile extension SDK and trying to invoke it on other SKU will cause this exception, because the type is not available.

    To enable the same functionality on all systems, you will need to use the new universal back button event:

    SystemNavigationManager.GetForCurrentView().BackRequested += BackButtonHandler;
    

    This will work the same on phone, PC, tablets,Xbox One, Surface Hub and HoloLens.

    On PC this button is not shown by default, so you have to display it manually or create your own. To show the Back button in window's title bar, use:

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

    It is recommended that you hide this button once Frame.CanGoBack is false, because in that case the button is no longer useful. You should do this after each navigation of the frame. Best place to do this is when setting up the root frame in App.xaml.cs:

     Frame rootFrame = Window.Current.Content as Frame;
     rootFrame.Navigated += UpdateAppViewBackButton;
    

    Now the handler could look like this:

    private void UpdateAppViewBackButton( object sender, NavigationEventArgs e )
    {
        Frame frame = (Frame) sender;
        var systemNavigationManager = SystemNavigationManager.GetForCurrentView();
        systemNavigationManager.AppViewBackButtonVisibility =
            frame.CanGoBack ? AppViewBackButtonVisibility.Visible : 
                              AppViewBackButtonVisibility.Collapsed;
    }
    

    On Application close

    I have also noticed that you are using Application.Current.Exit(); to exit the app. This is however not recommended. Once the user chooses OK in the dialog, you should rather set the e.Handled = false and let the system handle the app close manually. This will ensure the app suspension will run as expected and the app will stay in memory if the system has enough resources and will then launch faster again. Application.Current.Exit() kills the application and it is not recommended for UWP apps.

    One thing to remember is that on Desktop, there is currently no way to catch the user clicking the close button in the app's title bar, so your confirmation dialog will not display in that case unfortunately.