MVVMLight 子窗体传递数据
(2011-10-19 19:39:51)
标签:
mvvmlight传递参数子窗体父窗体传值消息杂谈 |
分类: .net4.0 |
额,继续写点东西吧,弄个比较实在点的实例出来,这个实例非常的简单,就是页面通过点击一个按钮,弹出一个ChildWindow 来进行选择某条记录,然后将在Page中获取ChildWindow中选择的记录。
假设调用ChildWindow的页面(page)为
Parent,对应的VM
被调用的ChildWindow 的页面为 (childwindow)Child 对应的VM ChildViewModel
既然用MVVM模式,那么在ChildWindow中也要使用MVVM模式,now begin
实现思路如下:
1 在Parent的OnNavigatedTo中注册消息,在该消息的会调函数中打开Child
// parent.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
你可能会问,为什么要在.cs 中写代码呢,为什么不在VM的构造函数中写呢,其实是有原因的,我们想想VM的好处之一就是可以将View 和 业务逻辑彻底的分开,例如以后想要将silverlight项目修改成WPF的项目,我们只需要简单的将WPF的View绑定一下就OK了,但是VM不是万能的,我们在silverlight项目中独有的一些东西怎么能够替换到WPF中呢,例如ChildWindow,如果我们见ChildWindow的打开事件写到的ViewModel中,那么以后移植就会有花费更多的额外劳动,所以就将ChildWindow 的打开写在了Parent.cs中,也许你会问,那么直接在Button的Click事件中写不就完事了吗,其实也未必不可,但是以后的附加工作也会很多,你从Child中选择的记录怎样提交到ParentViewModel中?别忘了,我们应用的还是MVVM模式。
2 既然是选择某条记录,那么就可以这样的往下推,既然是要选择记录,那么在ChildViewModel 中就要有一个备选的集合属性 ,怎样获取的我就不管了,如:
既然有集合,那么就要有选择项的
额,childwindow 中好像准备的差不多了
那么在ParentViewMode中该做些什么呢?当然,首先得有个接收选中的记录的属性吧,和ChildViewModel 中的相同。
额,那么他们怎样的进行传递呢?消息啊,这时候消息派上用场了,在ParentViewModel的构造中,我们注册一个消息。
Messenger.Default.Register<GenericMessage<UserInfo>>(this, "GetUserInfo", GetUserInfo);
// 回调
Private void GetUserInfo(GenericMessage<UserInfo> userInfo)
{
if (userInfo.Content != null)
}
在接下来就是一个连线的过程了,首先我们在ParentViewModel的 弹出选择窗体的事件中通知消消息OpenChildWindow à消息接收到之后调用回调函数弹出Childà在ChildViewModel中获取选择的记录给UserInfoSelectà通知消息GetUserInfo,并且传递UserInfoSelectàParentViewModel获取消息,调用回调方法,获取Child中选择的记录。Ok,工作以完成。
那么接下来就要说一些注意的事情了,既然有注册了消息,还有回调函数,就会出现多次被执行的情况(多次注册一个消息而没有注销),那么我们就要记住一定要在适当的位置注销消息,例如在Child的Closing事件中注销事件,或者在Page的OnNavigatedFrom(NavigationEventArgs e)中写注销消息。
注销消息如下:
Messenger.Default.Unregister<GenericMessage<UserInfo>>( "GetUserInfo");
其实为什么不在ViewModel 中弹出窗体,其实还有一个原因,就是如果我们要在ViewModel中弹出窗体,那么我们就要知道UI中的Child,这也就是说ViewModel要引用UI,这样做就有些…