我正在使用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}}
答案 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;
}
}