MVVM模式View和ViewModel的通信
还需要些什么呢
在前⾯⼏篇博客中我们尝试去实现了MVVM中的数据绑定、命令绑定和事件绑定。貌似实现的差不多了。我最早尝试⽤MVVM去开发的时候也是这么想的,没有⽤第三⽅框架,甚⾄只是实现了数据绑定和命令绑定就开搞了,遇到需要订阅事件的时候就把代码写在后台。那时候经常⾃我洗脑:设计模式是死的,⼈是活的,不能犯教条主义错误,后台写点代码影响不⼤。我确实很好的贯彻了这个思想,逻辑⾃然是乱得⼀塌糊涂。后来认真学习了下,实现了事件绑定,感觉好了很多。但确⾛向了另⼀个极端,后台代码多写⼀⾏都会感觉很不爽。还有就是View和ViewModel的依赖,例如当需要在ViewModel中打开窗⼝,给窗⼝传值,在窗⼝关闭后获取返回值时,打开窗体的动作在ViewModel中进⾏吗?这样ViewModel⼜产⽣了对View的依赖了。还有当主窗体按下⼀个按钮,然后需要另外⼀个窗体做出响应的时候,窗体间要如何通信。当在ViewModel中使⽤其它线程影响到UI时怎么处理。这篇博客主要对这些问题简单说明⼀下。
View和ViewModel的通信
消息通信的⽅式主要受到MVVMLight的启发,MVVMLight实现了⼀套略有复杂的消息通信,包含了定类型发送、分组发送、发送给包含继承类型的⽬标、⼴播等。就⽬前我做的⼏个⼩项⽬来说,View和ViewModel通信本⾝⽤的就不是那么频繁,需求也不算旺盛,所以⾃⼰实现了⼀套⽐较简易的消息通信。
View在实例化的时候注册消息,通过⼀个列表保存注册的消息,消息在发送的时候根据条件从列表中到相应的消息并执⾏操作,如下图所⽰:
消息发送和处理:
⽐较奇怪的是为什么要引⼊⼀个消息注册器,在View的后台代码中直接注册不就可以了吗?好吧,其实最初的想法确实⽐较强迫症,只是单纯的不想在后台中写⼊太多的代码(我真不是处⼥座),这样看上去似乎更⾼端。不过后来想了下,View对ViewModel(虽然不是接⼝)和消息注册器实际上都算是⼀种依赖,⽽且View对ViewModel和消息注册器的依赖都是唯⼀的,也就是说⼀个View只有⼀个ViewModel和⼀个消息注册器。这样可以⽤控制反转的⽅式把对ViewModel和消息注册器的依赖⼀起注⼊进来,⽽且在注⼊过程中可以顺便配置ViewModel的Dispatcher以⽅便跨线程修改UI,也可以给ViewModel配置单独的MessageManager让View和ViewModel的通信进⼊另⼀个次元,不受其他消息⼲扰。这些在讨论ViewModel依赖注⼊的时候将会尝试。
view ui框架关于跨线程修改UI
这个顺带提⼀下,因为实现起来很简单。在ViewModel中有时会遇到使⽤其它线程修改UI的情况,我之前是通过
App.Current.MainWindow.Dispatcher来获取UI线程的调度器的。当然也可以把UI线程的调度器保存到⼀个静态变量中以便随时访问。不过我⼀直没搞明⽩MaiWindow的Dispatcher和⾮MainWindow的Dispatcher有什么区别,不过还是在ViewModel的基类中加⼊了Dispatcher这个属性,这样在给View注⼊ViewModel的时候可以把ViewModel的Dispatcher设置为绑定的View的Dispatcher,虽然并不太清楚这有什么卵⽤ -_-|||

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。