还需要些什么呢

在前面几篇博客中我们尝试去实现了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依赖注入的时候将会尝试。

关于跨线程修改UI

这个顺带提一下,因为实现起来很简单。在ViewModel中有时会遇到使用其它线程修改UI的情况,我之前是通过 App.Current.MainWindow.Dispatcher来获取UI线程的调度器的。当然也可以把UI线程的调度器保存到一个静态变量中以便随时访问。不过我一直没搞明白MaiWindow的Dispatcher和非MainWindow的Dispatcher有什么区别,不过还是在ViewModel的基类中加入了Dispatcher这个属性,这样在给View注入ViewModel的时候可以把ViewModel的Dispatcher设置为绑定的View的Dispatcher,虽然并不太清楚这有什么卵用 -_-|||

MVVM模式View和ViewModel的通信的更多相关文章

  1. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  2. js架构设计模式——MVVM模式下,ViewModel和View,Model有什么区别

    MVVM模式下,ViewModel和View,Model有什么区别 Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就 ...

  3. WPF学习笔记:MVVM模式下,ViewModel如何关闭View?

    原文:http://blog.csdn.net/leftfist/article/details/32349731 矫枉过正,从一个极端走向另一个极端.MVVM模式,View只负责呈现,虽然也有后台代 ...

  4. MVVM模式下,ViewModel和View,Model有什么区别

    摘自正美的5群 Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就是展现出来的用户界面. 基本上,绝大多数软件所做的工 ...

  5. wpf mvvm模式下 在ViewModel关闭view

    本文只是博主用来记录笔记,误喷 使用到到了MVVM中消息通知功能 第一步:在需要关闭窗体中注册消息 public UserView() { this.DataContext = new UserVie ...

  6. MVVM之View和ViewModel的关联

    概要: 将所有的VM在加载到Application的Static Resource中,然后在View中用标签指定. 实现: 1)采用特性指定要添加到StaticResource中的对象 public  ...

  7. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  8. MVVM模式用依赖注入的方式配置ViewModel并注册消息

    最初的想法 这次主要讨论下给View指定ViewModel的事情.一般来说给View指定ViewModel常用的方式有两种,一种是在View的后台代码中写DataContext = new ViewM ...

  9. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

随机推荐

  1. Pythonの坑

    Python closures and late binding A closure occurs when a function has access to a local variable fro ...

  2. 【题解】HAOI2018染色

    好坑啊不开心…… 其实这题的想法还是比较简单粗暴的.题目明示恰好xxx,显然排除斜率二分这个玩意儿,那么不就只剩下容斥了嘛…… 令 \(A_{x}\) 为恰好出现了 \(S\) 次的至少有 \(x\) ...

  3. BZOJ4870 [Shoi2017]组合数问题 【组合数 + 矩乘】

    题目链接 BZOJ4870 题解 \[ans = \sum\limits_{i = 0}^{\infty}{nk \choose ik + r} \pmod p\] 发现实际是求 \[ans = \s ...

  4. 洛谷 P3197 [HNOI2008]越狱 解题报告

    P3197 [HNOI2008]越狱 题目描述 监狱有连续编号为\(1-N\)的\(N\)个房间,每个房间关押一个犯人,有\(M\)种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可 ...

  5. java多线程 -- 原子量 变量 CAS

    多线程原子性问题的产生和解决 原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量. 1. volatile 保证内存可见性,可以查看atomic中变量是使用v ...

  6. Java EE之会话

    1.需要会话的原因 所有HTTP服务器技术都普遍采用HTTP会话的概念,并且Java EE也在规范中添加了对会话的支持. 维持状态 会话用于维持请求和请求之间的状态.HTTP请求自身是完全无状态的.从 ...

  7. Android中EditText显示明文与密码的两种方式

    效果图如下所述: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and ...

  8. config之安全(用户认证)

    config server 端: 配置账号密码: 那么config client如何连接带有认证的config server呢? 假设两个同时使用,属性的优先级比uri的优先级高.

  9. 五、java面向对象编程_3

    目录 十五.Object类 1.toString 2.equals 十六.对象转型(casting) 十七.动态绑定(多态) 十八.抽象类(abstract) 十九.final关键字 二十.接口 十五 ...

  10. POJ - 2976 Dropping tests && 0/1 分数规划

    POJ - 2976 Dropping tests 你有 \(n\) 次考试成绩, 定义考试平均成绩为 \[\frac{\sum_{i = 1}^{n} a_{i}}{\sum_{i = 1}^{n} ...