处理 ViewModel 中的 OnNavieratedFrom / OnNavieratedTo 事件
我试图找出一种方法,让我的 ViewModel 在从或到导航页面时处理保存或恢复页面状态。
我尝试的第一件事是将 EventToCommand 行为添加到页面,但事件(OnNavieratedFrom 和 OnNavigedTo)被声明为受保护,并且 EventToCommand 看不到要绑定的事件。
接下来我想我会尝试使用 Messenger 类使用 View 的代码隐藏中的代码将消息传递给 ViewModel:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this);
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this);
base.OnNavigatedTo(e);
}
但这似乎有两个问题,首先是将此代码放在代码隐藏页面中。其次,如果不必为 PhoneApplicationPage 对象创建一组包装器类,ViewModel 就无法区分 OnNavieratedFrom 和 OnNavieratedTo 事件(请参阅下面的更新)。
处理这些事件对 MVVM-Light 最友好的方式是什么?
更新: 我能够通过像这样发送消息
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this,"NavigatedFrom");
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this, "NavigatedTo");
base.OnNavigatedTo(e);
}
并像这样注册它们来解决第二个问题:
Messenger.Default.Register<PhoneApplicationPage>(this, "NavigatedFrom", false, (action) => SaveState(action));
Messenger.Default.Register<PhoneApplicationPage>(this, "NavigatedTo", false, (action) => RestoreState(action));
I am trying to figure out a way for my ViewModel to handle saving or restore the page's state when the page is navigated From or To.
The first thing I tried was to add an EventToCommand behavior to the page, but the events (OnNavigatedFrom and OnNavigatedTo) are declared protected and the EventToCommand does not see the events to bind to.
Next I thought I would try using the Messenger class to pass a message to the ViewModel using code in the View's code behind:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this);
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this);
base.OnNavigatedTo(e);
}
But this seems to have two issues, first is having this code in the code behind page. Second, the ViewModel cannot tell the difference between the OnNavigatedFrom and the OnNavigatedTo events without having to create a set a wrapper classes for the PhoneApplicationPage object (see UPDATE below).
What is the most MVVM-Light friendly way to handle these events?
UPDATE:
I was able to resolve the second issue by Sending the Messages like this:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this,"NavigatedFrom");
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this, "NavigatedTo");
base.OnNavigatedTo(e);
}
and Registering them like this:
Messenger.Default.Register<PhoneApplicationPage>(this, "NavigatedFrom", false, (action) => SaveState(action));
Messenger.Default.Register<PhoneApplicationPage>(this, "NavigatedTo", false, (action) => RestoreState(action));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从代码后面执行命令比遍历整个消息传递要干净得多。毕竟,视图了解其 DataContext 并没有什么问题。
更新:传入NavigationContext.QueryString可能更有用,因为它已经解析出参数和值。
Executing a command from code behind is far cleaner than going through the whole messaging mess. After all there's nothing wrong with the view knowing about its DataContext.
Update: Passing in NavigationContext.QueryString is probably more useful, since it already parses out the parameters and value.
抱歉,这个问题迟到了三年。是的,我仍在使用 Silverlight。好的,我想将其写在
Page
代码隐藏中,如下所示:我正在使用如下扩展方法:
扩展方法意味着
Page
必须具有一个视图模型在DataContext
中实现IPageNavigationViewModel。对我来说,这是一种关注点分离的妥协,其中页面仅了解域中最通用的数据类型。这是界面:Sorry for being three years late to this question. Yes, I'm still using Silverlight. Okay I want to write it in
Page
code-behind like this:I am using an extension method like this:
The extension method implies that the
Page
must have a View Model that implements IPageNavigationViewModel inDataContext
. For me, this is a separation-of-concerns compromise where the Page knows only about the most general-purpose data types in the Domain. This the interface:看来您已经找到了解决问题的方法。我还建议执行以下操作:
查看使用 mvvm-toolkit 中提供的消息值之一,例如:
像这样:
Looks like you have a solution to your problem already. I would also suggest the following:
Look at using one of the message values provided in the mvvm-toolkit, such as:
Like this:
我认为 Ryan 的意思是,您使用 PhoneApplicationPage 作为正在发送的消息,而不是实际的消息。
您正在执行以下操作:
发送一条 PhoneApplicationPage 类型的消息。您可能不需要将整个 PhoneApplicationPage 作为消息发送。
您可以为 NavigatingTo / NavigatingFrom 创建一些消息,即。
我确信有一百万种更好的方法可以做到这一点
,我只是按照你的设置方式进行。就我个人而言,我的 ViewModelBase 类具有 NavigatingTo/NavigatingFrom 方法,我重写视图中的相应方法并将它们发送到我的 ViewModel。
I think what Ryan was getting at, was the fact that you're using the PhoneApplicationPage as the message that is being sent, instead of an actual message.
You're doing this:
which is sending a message of type PhoneApplicationPage. You probably don't need to send the entire PhoneApplicationPage as the message.
You could make some messages for NavigatingTo / NavigatingFrom, ie.
etc.
I'm sure there are a million better ways to do this, I was just going along with how you had set things up. Personally, my ViewModelBase class has NavigatingTo/NavigatingFrom methods and I override the respective methods in the View and send them to my ViewModel.
我使用问题中的更新答案制作了一个示例:
MainViewModel.xaml.cs:
MainViewModel.xaml.cs:
I make a sample using the updated answer inside the question :
MainViewModel.xaml.cs :
MainViewModel.xaml.cs :