使用 MVVMLight 消息通知
欢迎阅读我的MVVMLight教程系列文章《关于 MVVMLight 设计模式系列》
在文章的其实我们就说了,MVVMLight的精华就是消息通知机制,设计的非常不错。这个东西在MVVMLight可以说是用的及其的频繁,当 ViewModel请求View要有些改变的时候(比如弹个窗体)那么你在ViewModel里面编写弹窗的代码?那也就违背了MVVM的设计模式 啦,MVVMLight的消息通知可以实现互相调用代码而不耦合!
如何使用 MVVMLight 消息通知
接着我们上一篇文章的项目,也说过我们这里要修改项目中的不足之处,让代码优雅起来。目前为止我们一共有两个窗体(MainWindow
、UserView
),一个ViewModel(UserViewModel
)。我们在使用MainWindow
弹出UserView
的时候是直接编写的MainWindow
中的Button
的Click
事件。这样使得MainWindow
掌握了业务逻辑,按理什么时候合理的弹出UserView
应该是编写ViewModel的人员来决定的。所以我们应该把这个弹出窗口的权利交给ViewModel。
或许至此你会想在ViewModel中编写如下代码?
- UserView uv = new UserView();
- uv.Show()
但是这样写,对吗?…要是View的编写人员还没有编写出UserView
这个类呢?是不是还是没有脱离耦合?还是有这样的依赖性,不是View依赖ViewModel,就是ViewModel依赖View,如何解决?
下面我们来看看MVVMLight中的解决办法 – 消息通知
ViewModel是掌握业务逻辑的类,所以我们这里广播一个消息,主意!我这里说的是广播!并不是我要指定这个消息发送给谁。
我在 UserViewModel.cs 中使用了如下代码进行了消息广播。
- Messenger.Default.Send<object>(null, "ShowUserView");
这个消息发送了个广播,广播的令牌为"ShowUserView"
,这是个令牌! 跟一个暗语一样,哈哈!只要对的上的就可以收到这个消息,所以我们跟接收者(也就是编写View的工程师)进行约定。到时候接收消息就靠这个令牌了。
这里广播出去的参数是 Object 类型的,由于我什么参数都不需要传递所以我设定了 Send<T> 这个泛型为 object ,参数值为 null (也就是第一个参数)。
接收MVVMLight的消息
约定好了一个令牌(这里是“ShowUserView”
),我在此注册该令牌,有该令牌的消息时我会收到这个通知,看看我们在View中是如何注册消息并使用的吧!MainWindow.cs
的消息通知部分代码如下!
- public MainWindow()
- {
- this.DataContext = new MainWindowViewModel();
- InitializeComponent();
- //注册MVVMLight消息
- Messenger.Default.Register<object>(this, "ShowUserView", ShowUserView);
- //卸载当前(this)对象注册的所有MVVMLight消息
- this.Unloaded += (sender, e) => Messenger.Default.Unregister(this);
- }
- //弹出UserView窗体
- void ShowUserView(object obj)
- {
- new UserView().Show();
- }
先看看注册MVVMLight消息的那行代码吧,Register<T> 这里是一个泛型是和我们约定好的一样,我给了object类型,所以我们构建的方法的时候也是要要有一个object类型的参数的方法ShowUserView(object obj)
。
ok,再继续看看这行代码后面的三个参数。
第一个:this
表示注册该消息的对象,也就是消息接收人的意思,所以我填写当前窗体。
第二个: "ShowUserView"
就是令牌了,跟ViewModel的编写人员约定好的。
第三个:收到消息时要执行的方法,这里我们注册的是 ShowUserView(object obj)
这个方法。
至此,完美! 谁也不依赖谁!什么时候弹出窗体,这些业务逻辑交给ViewModel的编写人员吧。至于弹出什么窗体,窗体多漂亮,窗体怎么设置什么的,这就是编写View的事儿了。
似乎还有个没讲…..卸载消息?
有注册肯定有注销咯,如果你不注销的话,这个注册会一直存在。如果你打开了两次MainWinodw则会注册两次。。两个窗体都开着那么收到一条消息的时候就会弹出4个UserView窗体..原因很简单就是因为注册了两次。。。每个窗体就收到两次。。
所以我们在关闭窗体的时候或者你需要停止接收消息的时候来注销消息接受。。。到这里你应该明白 MVVMLight的消息注册机制是一个静态变量在App中全局广播与注册。带来的麻烦确实有,但是有时候也异常的方便。不会存在多个窗体接力传递对象过去使用的情况。
所以我这里在Unloaded
事件中对消息进行了注销,下面看看注销的代码
- Messenger.Default.Unregister(this);
这个是注销当前对象的所有消息,如果你想注销指定的消息,那么是有重载的,可以指定令牌的名称,如“ShwoUsreView”,敲敲代码试试吧!如下所示!
- Messenger.Default.Unregister<object>(this, "ShowUserView");
本文示例源码下载:MVVMLightDemo_4
至此MVVMLight的消息通知就差不多啦,有疑问或者其他的建议…欢迎在此回复进行讨论!
欢迎阅读我的MVVMLight教程系列文章《关于 MVVMLight 设计模式系列》 MVVMLight相关的我会在该目录中进行补充。
转载请注明:王旭博客 » 使用 MVVMLight 消息通知
使用 MVVMLight 消息通知的更多相关文章
- MVVMLight消息通知实现机制详解(二)
接上文 MVVMLight消息通知实现机制详解(一) 该工具的内部主要逻辑是以字典模式进行储存持有订阅对象设置的传入参数Type类型.Key值.Action.Target(订阅对象本身) 在发生订阅事 ...
- MVVMLight消息通知实现机制详解(一)
最近对委托.事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下: 一.开发中遇到的问题: 场景1:ClassA中存在事 ...
- UWP消息通知
在Windows 10通常是使用Toast通知方式进行的消息通知,但是在应用通知是不需要通知带有音效的,但是又不能在系统通知中心留下记录,那么需要监听ToastNotification实例的Dismi ...
- Redis系列二之事务及消息通知
一.事务 Redis中的事务是一组命令的集合.一个事务中的命令要么都执行,要么都不执行. 1.事务简介 事务的原理是先将一个事务的命令发送给Redis,然后再让Redis依次执行这些命令.下面看一个示 ...
- Redis笔记(六)Redis的消息通知
Redis的消息通知可以使用List类型的LPUSH和RPOP(左进右出),当然更方便的是直接使用Redis的Pub/Sub(发布/订阅)模式. >>使用List实现队列 使用列表类型的L ...
- 使用 Windows10 自定义交互消息通知
消息通知是最常用的应用功能之一了,但是由于平台的差异,IOS Android 以及 Windows 都有其特殊性,Android开发者在国内常常都是使用三方的一些推送服务,或者是使用自建的服务器为应用 ...
- Android中的消息通知(NotificationManager和Notification)
下面来谈谈notification,这个notification一般用在电话,短 信,邮件,闹钟铃声,在手机的状态栏上就会出现一个小图标,提示用户处理这个通知,这时手从上方滑动状态栏就可以展开并处理这 ...
- Android消息通知(notification)和PendingIntent传值
通知栏的自定义布局:转:http://blog.csdn.net/vipzjyno1/article/details/25248021 拓展 实现自定义的通知栏效果: 这里要用到RemoteViews ...
- cordova的android notify消息通知插件
最近在学习用CORDOVA(PHONEGAP)结合SENCHA TOUCH开发应用,想实现一个安卓下的消息通知功能,这个可以通过CORDOVA的插件来实现. 插件目录结构如下: notifyplugi ...
随机推荐
- Qt入门-layout布局
开发一个图形界面应用程序,界面的布局影响到界面的美观.在设计一个界面之前,应该考虑到开发的界面可能给不用的用户使用,而用户的屏幕大小.纵横比例.分辨率可能不同,界面还可能是可缩放的,程序应该可以适应这 ...
- LeetCode: Reverse Words in a String 解题报告
Reverse Words in a String Given an input string, reverse the string word by word. For example,Given ...
- 基于HTML5 Canvas粒子效果文字动画特效
之前我们分享过很多超酷的文字特效,其中也有利用HTML5和CSS3的.今天我们要来分享一款基于HTML5 Canvas的文字特效,输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的 ...
- 【Unity笔记】常用插件
记录一些常见插件,随时补充. iTween动画插件 原理:插值法,给出初始值和终点值,自动算出中间值. DoTween Tween动画 Playmaker $45 Playmaker由第三方软件商Hu ...
- Ubuntu下安装Apache
Ubuntu为我们提供了 su apt-get install 命令,通过它你可以很方便地安装一些软件,这些软件是放在Ubuntu放置在各个地方的服务器上面,如果你想安装的软件是比较常见的,一般都可以 ...
- 求链表倒数第k个节点
程序员面试题6-查找链表中倒数第k个结点 (-- ::)转载▼ 标签: 杂谈 分类: 程序设计 题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下 ...
- JavaScrip——初学(三个常用对话框及方法调用)
一. 三个常用对话框: 1.都必须写在<scrip></scrip> <body> <font>alert("报错")</fo ...
- 机器学习:K-Means聚类算法
本文来自同步博客. 前面几篇文章介绍了回归或分类的几个算法,它们的共同点是训练数据包含了输出结果,要求算法能够通过训练数据掌握规律,用于预测新输入数据的输出值.因此,回归算法或分类算法被称之为监督学习 ...
- 第一次使用bootstrap3做的响应式网站
第一次使用bootstrap3,发现对移动支持得不错,可以很快的开发出一个支持移动和PC端的网站 作为一个后台程序员觉得得界面做得还可以, 按以前是只能自己看看了 时间线来自国外网站,使用到的css如 ...
- Spark读取文件
spark默认读取的是hdfs上的文件. 如果读取本地文件,则需要加file:///usr/local/spark/README.md. (测试时候发现,本地文件必须在spark的安装路径内部或者平行 ...