简体   繁体   中英

Overriding the Back Button in Prism for Windows Phone 8.1 Runtime

I'm using the Prism MVVM library for WinRT in a Windows Phone 8.1 project. Is it possible to prevent back navigation via the phone's back button and handle the back button press in the ViewModel?

Concrete scenario:

  • The user can select one item (the "active" item) from a list of items - like a player in a game. That item is a reference for the rest of the app's functionality, eg database queries.
  • Selecting one item returns the user to the previous (main) page.
  • In the same list, the user can also delete an item that is no longer needed. It should be possible to delete all items.

Problem: If the user deletes the active item or the last item and then taps the back button, I end up having an invalid active item.

To prevent that, I'd like to cancel the back button navigation and prompt the user to select or create another active item, ideally from the ViewModel.


Update: I have now added an event handler to the App.xaml.cs based on how I understood Nate's comment below. This should override it application-wide:

private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
    Frame currentFrame = Window.Current.Content as Frame;
    if (currentFrame == null)
    {
        return;
    }
    if (currentFrame.Content is SelectionPage)
    {
        e.Handled = true;
    }
    else if (currentFrame.CanGoBack)
    {
        currentFrame.GoBack();
        e.Handled = true;
    }
}

and subscribing to the event in the constructor:

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

This seems to be handling the back button press just fine but it does not stop the existing navigation. So it goes back in any case and twice in the default case.

This is possible. Here is the solution (mostly inspired by this discussion ):

Create an interface that allows view models to disable the back navigation:

public interface IRevertState
{
    bool CanRevertState();
    void RevertState();
}

In the view model implement the interface:

public class myViewModel : ViewModel, IRevertState {
public bool CanRevertState() {
    return (...) //condition under which back navigation should be disabled
}
public void RevertState() {
    (...) // optionally reset condition if required
}

In App.Xaml.cs handle the back navigation:

#if WINDOWS_PHONE_APP
    protected override void OnHardwareButtonsBackPressed(object sender, BackPressedEventArgs e) {
        var page = (Page)((Frame)Window.Current.Content).Content;
        if (page.DataContext is IRevertState) {
            var revertable = (IRevertState)page.DataContext;
            if (revertable.CanRevertState()) {
                revertable.RevertState();
                e.Handled = true;
                return;
            }
        }
        base.OnHardwareButtonsBackPressed(sender, e);
    }
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM