如何使用MVVM光处理WP 8.1上的后退按钮?

时间:2015-01-23 22:13:26

标签: c# mvvm windows-phone-8.1 winrt-xaml mvvm-light

我正在使用MVVM light 5上提供的NavigationService搜索Windows Phone 8.1 WinRT上处理后退按钮事件的适当方式。

到目前为止,我认为最好的方法是在ViewModelLocator内注册GoBack NavigationService方法,同时根据NavigationService in MVVM Light V5中列出的方法创建public class ViewModelLocator { public ViewModelLocator() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); // Register NavigationService SimpleIoc.Default.Register(CreateNavigationService); // Register ViewModels here } private INavigationService CreateNavigationService() { var navigationService = new NavigationService(); // Register pages here navigationService.Configure("Details", typeof(DetailsPage)); // Handle back button HardwareButtons.BackPressed += (sender, args) => { navigationService.GoBack(); args.Handled = true; }; return navigationService; } } 方法

这是一种有效的方法。但是,在导航之前我无法处理验证,因此我想知道是否有更合适的方法来处理此事件。

{{1}}

3 个答案:

答案 0 :(得分:3)

如果你看一下Marco如何在博客文章中启用OnNavigatedTo和OnNavigatedFrom调用传播到ViewModel

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

您会注意到他使用了INAVigable接口以及Activate和Deactivate方法。您可以使用AllowGoingBack方法扩展该INavigable接口,如下所示:

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

每个与页面相关的ViewModel都可以根据上下文拥有自己的AllowGoingBack方法实现。然后,在View后面的代码中(可以,因为View可以了解ViewModel),您可以覆盖OnNavigatingFrom并检查是否应该允许返回:

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;
        }
    }
}

然后,您的ViewModel将实现INAVigable,因此您将在AllowGoingBack()中定义验证代码,如果返回,则返回true,如果不是,则返回false。

答案 1 :(得分:0)

根据igrali的回答,并按照Calling ViewModel methods in response to Page navigation events using MVVM Light in WinRT中的说明,我在" BindablePage.cs"中做了什么。 class,在OnNavigatedTo方法中添加以下内容:

            HardwareButtons.BackPressed += HardwareButtons_BackPressed;

并在OnNavigatedFrom中:

            HardwareButtons.BackPressed -= HardwareButtons_BackPressed;

然后添加事件处理程序:

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

接下来,在INAVigable界面中添加

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

最后,在每个视图模型上:

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 WINDOWS_PHONE_APP ... #endif

包围这些新代码

答案 2 :(得分:0)

我发现了一篇关于你问题的有趣文章:http://blog.falafel.com/windows-phone-and-mvvm-light-navigationservice-and-cangoback/

这是个主意:

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;
   }
 }