还需要些什么呢

在前面几篇博客中我们尝试去实现了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. bzoj 2124 等差子序列 (线段树维护hash)

    2124: 等差子序列 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 1922  Solved: 714[Submit][Status][Discuss ...

  2. hdu-3308 LCIS (线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. ZJOI2018酱油记

    ZJOI2018酱油记 前言 作为\(HN\)高一蒟蒻选手,毕竟去了趟\(ZJOI\)玩泥巴 不写点游记还是不太好吧. 今天来补一补. Day0 星期天,中午,我们一群人滚到了学校门口 然后集合,滚去 ...

  4. 【bzoj2780】 Sevenk Love Oimaster

    http://www.lydsy.com/JudgeOnline/problem.php?id=2780 (题目链接) 题意 给出很多主串和很多询问串,求一个询问串在多少主串中出现过 Solution ...

  5. 20135319zl软件破解报告

    编写一个简单的C程序.要求只有输入a,才能通过. 现在,使用objdump –d po反汇编这个程序 找到main函数,可以发现movb $0x61,0x1f(%esp)这句语句中是将字符a(对应0x ...

  6. Java的基本类型

    基本数据类型的加载和存储 极客时间深入理解Java虚拟机读后感,有错误还请指正 虚拟机中的Boolean类型 在Java语言规范中,boolean类型的值只有两种可能,那就是"true&qu ...

  7. win10不能被远程解决方案(开启远程桌面,防火墙仍不能被远程解决方案)

    开启远程桌面,防火墙仍不能被远程解决方案 1.“Win+R”→“gpedit.msc” 2.依次展开“计算机配置”→“管理模版”→“系统”→“凭据分配”→找到“允许分配保存的凭据用于仅NTLM服务器身 ...

  8. [opencv] 图像几何变换:旋转,缩放,斜切

    几何变换 几何变换可以看成图像中物体(或像素)空间位置改变,或者说是像素的移动. 几何运算需要空间变换和灰度级差值两个步骤的算法,像素通过变换映射到新的坐标位置,新的位置可能是在几个像素之间,即不一定 ...

  9. Kubernetes集群中Service的滚动更新

    Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经“全天候化”,为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足 ...

  10. RACCommand

    RACCommand是ReactiveCocoa中用于表示UI操作的一个类.它包含一个代表了UI操作的结果的信号以及标识操作当前是否被执行的一个状态. 1.创建新的RACCommand self.ex ...