locked
Handling Back Button press. RRS feed

  • Question

  • My app currently has multiple pages. Depending on the page I want to handle the back button press in a certain way. For example if I am on my 'MainPage' and the back button is pressed I want the application to exit. If I am on 'BlankPage1' I want a 'menu' to appear with the back button. When on 'Info' or 'TopScores' I want the back button to navigate back to 'MainPage'. Currently everything is working except for 'Info' and 'TopScores'. If I just open the application and go to either 'Info' or 'TopScores' and press the back button, the app will be suspended. If I first navigate to 'BlankPage1' and press the back button and end up going to 'MainPage' via my menu and then navigate to 'Info' or 'TopScores' and press the back button it works as I want by navigating back to 'MainPage'.

    So how do I navigate to 'MainPage' with the back button when on 'Info' or 'TopScores' instead of what is happening currently?

    Here is my code:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Windows;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    using Windows.Phone.UI.Input;
    
    // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkID=390556
    
    namespace Rush
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class BlankPage1 : Page
        {
            private Boolean gamePaused;
    
            public BlankPage1()
            {
                this.InitializeComponent();
                HardwareButtons.BackPressed += HardwareButtons_BackPressed;
                gamePaused = false;
                this.NavigationCacheMode = NavigationCacheMode.Required;
            }
    
            private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
            {
                gamePaused = true;
                Frame current = Window.Current.Content as Frame;
    
                if(current.Content is MainPage && current.Content != null)
                {
                   Application.Current.Exit();
                }
    
                else if(current.Content is BlankPage1 && current.Content != null)
                {
                    PauseBorder.Visibility = Windows.UI.Xaml.Visibility.Visible;
                    e.Handled = true;
                    //pauseGame();
                }
                
                else if(current.Content is Info && current.Content != null)
                {
                    this.Frame.Navigate(typeof(MainPage));
                    e.Handled = true;
                }
    
                else if(current.Content is TopScores && current.Content != null)
                {
                    this.Frame.Navigate(typeof(MainPage));
                    e.Handled = true;
                }
            }
    
            /// <summary>
            /// Invoked when this page is about to be displayed in a Frame.
            /// </summary>
            /// <param name="e">Event data that describes how this page was reached.
            /// This parameter is typically used to configure the page.</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                 
            }
     
            // Exits application from current spot
            private void QuitButton_Click(object sender, RoutedEventArgs e)
            {
                Application.Current.Exit();
            }
    
            // Goes to home page
            private void HomeButton_Click(object sender, RoutedEventArgs e)
            {
                this.Frame.Navigate(typeof(MainPage));
                gamePaused = false;
                //clearGame();
            }
    
            // Resumes game
            private void ResumeButton_Click(object sender, RoutedEventArgs e)
            {
                gamePaused = false;
                PauseBorder.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                //resumeGame();
            }      
        }
    }
    

    Thanks

    Tuesday, January 13, 2015 8:59 PM

Answers

  • If I just open the application and go to either 'Info' or 'TopScores' and press the back button, the app will be suspended

    How are you getting to the Info or TopScores pages in this case?

    The typical way to handle the back button is to always do Frame.Navigate to go forwards and do Frame.GoBack to back out. The Frame.Navigate call will put the current page on the back stack and then GoBack will back up.

    HardwareButtons_BackPressed shouldn't need to keep track of where it is itself or call Frame.Navigate to do a forward navigation. It can leave this up to the back stack:

    private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) {

    Frame current = Window.Current.Content as Frame; // If we're not on the entry page we // should be able to go back, so do so if(current.CanGoBack) { // unwind the back stack current.GoBack(); // Mark handled so we don't back out of the app e.Handled = true; } // Otherwise let the default handling occur // which will back out of the app to the // start screen (or wherever) }


    You'll have to add your pause handling code in, but that probably should be on the page's OnNavigateTo or OnNavigateFrom methods rather than on the back button itself. I would probably put it on the NavigateFrom method of the gameplay page. This will also catch if the user navigates away via the start button.

    The only trickiness is if you provide a way for the user to launch the app directly to a secondary page (Info,  TopScores, etc.) via a Live Tile or similar. In that case you'll need to juggle a bit to get the MainPage onto the back stack: instead of launching directly to Info, call Frame.Navigate to navigate to MainPage and pass a parameter which says to continue on to the real launch page. MainPage's OnNavigateTo method can then call Frame.Navigate again to bounce to the real target and leave MainPage in the back stack.

    Windows Phone apps shouldn't call Application.Exit. Leaving BackPressed unhandled will by default back out of the app and let the user suspend it for later re-entry. See Application lifecycle for more information on how this should work.

    Tuesday, January 13, 2015 10:08 PM

All replies

  • If I just open the application and go to either 'Info' or 'TopScores' and press the back button, the app will be suspended

    How are you getting to the Info or TopScores pages in this case?

    The typical way to handle the back button is to always do Frame.Navigate to go forwards and do Frame.GoBack to back out. The Frame.Navigate call will put the current page on the back stack and then GoBack will back up.

    HardwareButtons_BackPressed shouldn't need to keep track of where it is itself or call Frame.Navigate to do a forward navigation. It can leave this up to the back stack:

    private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) {

    Frame current = Window.Current.Content as Frame; // If we're not on the entry page we // should be able to go back, so do so if(current.CanGoBack) { // unwind the back stack current.GoBack(); // Mark handled so we don't back out of the app e.Handled = true; } // Otherwise let the default handling occur // which will back out of the app to the // start screen (or wherever) }


    You'll have to add your pause handling code in, but that probably should be on the page's OnNavigateTo or OnNavigateFrom methods rather than on the back button itself. I would probably put it on the NavigateFrom method of the gameplay page. This will also catch if the user navigates away via the start button.

    The only trickiness is if you provide a way for the user to launch the app directly to a secondary page (Info,  TopScores, etc.) via a Live Tile or similar. In that case you'll need to juggle a bit to get the MainPage onto the back stack: instead of launching directly to Info, call Frame.Navigate to navigate to MainPage and pass a parameter which says to continue on to the real launch page. MainPage's OnNavigateTo method can then call Frame.Navigate again to bounce to the real target and leave MainPage in the back stack.

    Windows Phone apps shouldn't call Application.Exit. Leaving BackPressed unhandled will by default back out of the app and let the user suspend it for later re-entry. See Application lifecycle for more information on how this should work.

    Tuesday, January 13, 2015 10:08 PM
  • The way that I am getting to 'Info' and 'TopScores' is with a button and the following:

     private void InfoButton_Click(object sender, RoutedEventArgs e)
            {
                this.Frame.Navigate(typeof(Info));
            }
    
            private void TopScoresButton_Click(object sender, RoutedEventArgs e)
            {
                this.Frame.Navigate(typeof(TopScores));
            }

    Is this the problem with the app being suspended when I go back? Because I have buttons on the 'Info' and 'TopScores' pages that use the GoBack() method that work as intended but when I use the GoBack method and handle the event when the back button is pressed on those two pages (I have changed my code from what I originally posted) it does not take me back to the prior page. Also in my method for handling the back button pressed if I do:

    Frame current = Window.Current.Content as Frame;
    
    if(current.Content is TopScores || current.Content is Info)
    {
        Debug.WriteLine("I am here");
    }

    This will never write the message but works if I use my other pages like 'BlankPage1'. I will do some more reading on this topic.

    Thank you for the advice, it will be helpful.



    • Edited by DigitalMath Wednesday, January 14, 2015 3:52 AM
    Wednesday, January 14, 2015 2:24 AM