How to handle the back button on WP 8.1 using MVVM light?

跟風遠走 提交于 2019-12-04 12:13:36

If you take a look at how Marco is enabling OnNavigatedTo and OnNavigatedFrom calls to propagate to ViewModel in the blog post

Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT

you'll notice he uses INavigable interface and Activate and Deactivate methods. You could extend that INavigable interface with AllowGoingBack method, like this:

public interface INavigable
{
    void Activate(object parameter);
    void Deactivate(object parameter);
    bool AllowGoingBack();
}

Each page-related ViewModel can then have its own implementation of AllowGoingBack method depending on the context. Then, in the code behind of the View (which is OK, because View can know about the ViewModel) you can override OnNavigatingFrom and check if going back should be allowed:

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    var navigableViewModel = this.DataContext as INavigable;

    if (navigableViewModel != null)
    {
        if (e.NavigationMode == NavigationMode.Back && !navigableViewModel.AllowGoBack())
        {
            e.Cancel = true;
        }
    }
}

Your ViewModel would then implement INavigable, so you would define the validation code inside AllowGoingBack(), and return true if going back is OK, and false if it's not.

Based on the answer by igrali, and following the instructions in Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT, what I did in the "BindablePage.cs" class, in the OnNavigatedTo method was to add add the following:

            HardwareButtons.BackPressed += HardwareButtons_BackPressed;

and in the OnNavigatedFrom:

            HardwareButtons.BackPressed -= HardwareButtons_BackPressed;

Then add the event handler:

        void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
        {
            var navigableViewModel = this.DataContext as INavigable;
            if (navigableViewModel != null)
                navigableViewModel.BackButonPressed(e);
        }

Next, in the INavigable interface add

void BackButonPressed(Windows.Phone.UI.Input.BackPressedEventArgs e);

And finally, on each view model:

public void BackButonPressed(Windows.Phone.UI.Input.BackPressedEventArgs e)
{
    // You can modify this code to show a confirmation dialog, etc...
    e.Handled = true;
    navigationService.GoBack(); 
}

If this is a universal app, then don't forget to surround these new pieces of code with #if WINDOWS_PHONE_APP ... #endif

I found an interesting article about your question: http://blog.falafel.com/windows-phone-and-mvvm-light-navigationservice-and-cangoback/

This is the idea:

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

private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
   var frame = Window.Current.Content as Frame;
   if (frame.CanGoBack)
   {
      var navigation = ServiceLocator.Current.GetInstance<INavigationService>();
            navigation.GoBack();
            e.Handled = true;
   }
 }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!