如何使用MVVM灯处理WP 8.1上的后退按钮?
我正在寻找适当的方法来使用MVVM light 5上提供的NavigationService
来处理Windows Phone 8.1 WinRT上的后退按钮事件。
到目前为止,我认为最好的地方是在ViewModelLocator
通过注册NavigationService
的GoBack
方法,同时按照MVVM Light V5中NavigationService中概述的方法创建它。
这是一种有效的方法。 但是,我在导航之前无法处理validation,因此我想知道是否有更合适的方法来处理此事件。
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; } }
如果你看一下Marco如何在博客文章中启用OnNavigatedTo和OnNavigatedFrom调用传播到ViewModel
使用WinRT中的MVVM Light调用ViewModel方法以响应页面导航事件
你会注意到他使用了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()中定义validation代码,如果返回正常则返回true,否则返回false。
基于igrali的回答,并按照WinRT中使用MVVM Light响应页面导航事件调用ViewModel方法中的指示,我在“BindablePage.cs”类中在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
包围这些新代码#if WINDOWS_PHONE_APP ... #endif
我发现了一篇关于你的问题的有趣文章: 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(); navigation.GoBack(); e.Handled = true; } }