26
votes

I have 2 pages in my Windows Phone 8.1 Universal App.

I navigate from Page1.xaml to Page2.xaml by using a button with the click event code:

this.Frame.Navigate(typeof(Page2));

When I am on Page2, and I use the hardware back button the app closes without an exception or anything. It just returns to the startscreen.

I already tried the following on Page 2:

public Page2()
    {
        this.InitializeComponent();
        Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
    }

    void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
    {
        Frame.GoBack();
    }

As far as I know I do not clear the back stack.

What is going on, and how can I fix this?

Kind regards, Niels

3

3 Answers

79
votes

This is new to Windows Phone 8.1.

If you create a new Hub Universal App using a VS2013 template, you'll notice a class in Common folder called a NavigationHelper.

This NavigationHelper gives you a hint how to properly react to back button press. So, if you don't want to use the NavigationHelper, here's how to get the old behavior back:

public BlankPage1()
{
    this.InitializeComponent();
    HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}

void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
    if (Frame.CanGoBack)
    {
        e.Handled = true;
        Frame.GoBack();
    }
}

You can also do it on app level, to avoid having to do it on every page:

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

    #if WINDOWS_PHONE_APP
    HardwareButtons.BackPressed += HardwareButtons_BackPressed;
    #endif
}

#if WINDOWS_PHONE_APP
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;

    if (rootFrame != null && rootFrame.CanGoBack)
    {
        e.Handled = true;
        rootFrame.GoBack();
    }
}
#endif
5
votes

If you want to show a confirmation dialog when you press the back button Make note the code below

    private async void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
    {
        e.Handled = true;
        if (Frame.CanGoBack)
        {
            Frame.GoBack();
        }
        else
        {
            var msg = new MessageDialog("Confirm Close");
            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();
            }
        }
    }
1
votes

You could use the NavigationHelper "pattern" witch also helps you to handle lifecyle events.

The NavigationHelper is a class provided by Microsoft (it isn't part of the Windows Phone API) where you are able to register your pages and the NavigationHelper takes care about the FrameHistory.

To use the NavigationHelper you have to add the class to your project and register the Pages at the NavigationHelper when they are loaded. When you add a BasicPage (not a BlankPage) to your project VisualStudio adds a folder called common with some helper classes including the NavigationHelper class.

To register your pages in the NavigationHelper you have to add the following code to all you pages where you want to the NavigationHelper.

public sealed partial class MySuperCoolPage : Page {
    private readonly NavigationHelper navigationHelper;

    public MySuperCoolPage() {
        InitializeComponent();
        navigationHelper = new NavigationHelper(this);
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e){
        this.navigationHelper.OnNavigatedFrom(e);
    }

    protected override void OnNavigatedTo(NavigationEventArgs e) {
        navigationHelper.OnNavigatedTo(e);
    }
}

For more Information about this Topic and the ability to handle life cycle events you could read this article or watch this video.