欢迎阅读我的MVVMLight教程系列文章关于 MVVMLight 设计模式系列

在文章的其实我们就说了,MVVMLight的精华就是消息通知机制,设计的非常不错。这个东西在MVVMLight可以说是用的及其的频繁,当 ViewModel请求View要有些改变的时候(比如弹个窗体)那么你在ViewModel里面编写弹窗的代码?那也就违背了MVVM的设计模式 啦,MVVMLight的消息通知可以实现互相调用代码而不耦合!

如何使用 MVVMLight 消息通知

接着我们上一篇文章的项目,也说过我们这里要修改项目中的不足之处,让代码优雅起来。目前为止我们一共有两个窗体(MainWindowUserView),一个ViewModel(UserViewModel)。我们在使用MainWindow弹出UserView的时候是直接编写的MainWindow中的ButtonClick事件。这样使得MainWindow掌握了业务逻辑,按理什么时候合理的弹出UserView应该是编写ViewModel的人员来决定的。所以我们应该把这个弹出窗口的权利交给ViewModel。

或许至此你会想在ViewModel中编写如下代码?

  1. UserView uv = new UserView();
  2. uv.Show()

但是这样写,对吗?…要是View的编写人员还没有编写出UserView这个类呢?是不是还是没有脱离耦合?还是有这样的依赖性,不是View依赖ViewModel,就是ViewModel依赖View,如何解决?

下面我们来看看MVVMLight中的解决办法 – 消息通知

ViewModel是掌握业务逻辑的类,所以我们这里广播一个消息,主意!我这里说的是广播!并不是我要指定这个消息发送给谁

我在 UserViewModel.cs 中使用了如下代码进行了消息广播。

  1. Messenger.Default.Send<object>(null, "ShowUserView");

这个消息发送了个广播,广播的令牌为"ShowUserView",这是个令牌! 跟一个暗语一样,哈哈!只要对的上的就可以收到这个消息,所以我们跟接收者(也就是编写View的工程师)进行约定。到时候接收消息就靠这个令牌了。

这里广播出去的参数是 Object 类型的,由于我什么参数都不需要传递所以我设定了 Send<T> 这个泛型为 object ,参数值为 null (也就是第一个参数)。

接收MVVMLight的消息

约定好了一个令牌(这里是“ShowUserView”),我在此注册该令牌,有该令牌的消息时我会收到这个通知,看看我们在View中是如何注册消息并使用的吧!MainWindow.cs 的消息通知部分代码如下!

  1. public MainWindow()
  2. {
  3. this.DataContext = new MainWindowViewModel();
  4. InitializeComponent();
  5. //注册MVVMLight消息
  6. Messenger.Default.Register<object>(this, "ShowUserView", ShowUserView);
  7. //卸载当前(this)对象注册的所有MVVMLight消息
  8. this.Unloaded += (sender, e) => Messenger.Default.Unregister(this);
  9. }
  10. //弹出UserView窗体
  11. void ShowUserView(object obj)
  12. {
  13. new UserView().Show();
  14. }

先看看注册MVVMLight消息的那行代码吧,Register<T> 这里是一个泛型是和我们约定好的一样,我给了object类型,所以我们构建的方法的时候也是要要有一个object类型的参数的方法ShowUserView(object obj)

ok,再继续看看这行代码后面的三个参数。

第一个:this  表示注册该消息的对象,也就是消息接收人的意思,所以我填写当前窗体。

第二个: "ShowUserView" 就是令牌了,跟ViewModel的编写人员约定好的。

第三个:收到消息时要执行的方法,这里我们注册的是  ShowUserView(object obj) 这个方法。

至此,完美! 谁也不依赖谁!什么时候弹出窗体,这些业务逻辑交给ViewModel的编写人员吧。至于弹出什么窗体,窗体多漂亮,窗体怎么设置什么的,这就是编写View的事儿了。

似乎还有个没讲…..卸载消息?

有注册肯定有注销咯,如果你不注销的话,这个注册会一直存在。如果你打开了两次MainWinodw则会注册两次。。两个窗体都开着那么收到一条消息的时候就会弹出4个UserView窗体..原因很简单就是因为注册了两次。。。每个窗体就收到两次。。

所以我们在关闭窗体的时候或者你需要停止接收消息的时候来注销消息接受。。。到这里你应该明白 MVVMLight的消息注册机制是一个静态变量在App中全局广播与注册。带来的麻烦确实有,但是有时候也异常的方便。不会存在多个窗体接力传递对象过去使用的情况。

所以我这里在Unloaded事件中对消息进行了注销,下面看看注销的代码

  1. Messenger.Default.Unregister(this);

这个是注销当前对象的所有消息,如果你想注销指定的消息,那么是有重载的,可以指定令牌的名称,如“ShwoUsreView”,敲敲代码试试吧!如下所示!

  1. Messenger.Default.Unregister<object>(this, "ShowUserView");

 本文示例源码下载MVVMLightDemo_4

至此MVVMLight的消息通知就差不多啦,有疑问或者其他的建议…欢迎在此回复进行讨论!

欢迎阅读我的MVVMLight教程系列文章关于 MVVMLight 设计模式系列》 MVVMLight相关的我会在该目录中进行补充。

转载请注明:王旭博客 » 使用 MVVMLight 消息通知

使用 MVVMLight 消息通知的更多相关文章

  1. MVVMLight消息通知实现机制详解(二)

    接上文 MVVMLight消息通知实现机制详解(一) 该工具的内部主要逻辑是以字典模式进行储存持有订阅对象设置的传入参数Type类型.Key值.Action.Target(订阅对象本身) 在发生订阅事 ...

  2. MVVMLight消息通知实现机制详解(一)

    最近对委托.事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下: 一.开发中遇到的问题: 场景1:ClassA中存在事 ...

  3. UWP消息通知

    在Windows 10通常是使用Toast通知方式进行的消息通知,但是在应用通知是不需要通知带有音效的,但是又不能在系统通知中心留下记录,那么需要监听ToastNotification实例的Dismi ...

  4. Redis系列二之事务及消息通知

    一.事务 Redis中的事务是一组命令的集合.一个事务中的命令要么都执行,要么都不执行. 1.事务简介 事务的原理是先将一个事务的命令发送给Redis,然后再让Redis依次执行这些命令.下面看一个示 ...

  5. Redis笔记(六)Redis的消息通知

    Redis的消息通知可以使用List类型的LPUSH和RPOP(左进右出),当然更方便的是直接使用Redis的Pub/Sub(发布/订阅)模式. >>使用List实现队列 使用列表类型的L ...

  6. 使用 Windows10 自定义交互消息通知

    消息通知是最常用的应用功能之一了,但是由于平台的差异,IOS Android 以及 Windows 都有其特殊性,Android开发者在国内常常都是使用三方的一些推送服务,或者是使用自建的服务器为应用 ...

  7. Android中的消息通知(NotificationManager和Notification)

    下面来谈谈notification,这个notification一般用在电话,短 信,邮件,闹钟铃声,在手机的状态栏上就会出现一个小图标,提示用户处理这个通知,这时手从上方滑动状态栏就可以展开并处理这 ...

  8. Android消息通知(notification)和PendingIntent传值

    通知栏的自定义布局:转:http://blog.csdn.net/vipzjyno1/article/details/25248021 拓展 实现自定义的通知栏效果: 这里要用到RemoteViews ...

  9. cordova的android notify消息通知插件

    最近在学习用CORDOVA(PHONEGAP)结合SENCHA TOUCH开发应用,想实现一个安卓下的消息通知功能,这个可以通过CORDOVA的插件来实现. 插件目录结构如下: notifyplugi ...

随机推荐

  1. bnuoj16491

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=16491 题意:有t组测试数据,每组测试数据第一行为n,m,接下来有n种跑法,m为最大的能力,每一种跑 ...

  2. 一款纯css3实现的机器人看书动画效果

    今天要给大家介绍一款纯css3实现的机器人看书动画效果.整个画面完全由css3实现的绘制,没有使用任何图片元素.机器人的眼睛使用了动画元素.我们一起看下效果图: 在线预览   源码下载 实现的代码. ...

  3. MongoDB学习之(三)增删查改

    发现一篇Java操作MongoDb不错的文章,记录一下: https://www.cnblogs.com/sa-dan/p/6836055.html 基本功能. import java.util.Ar ...

  4. Rocket重试机制,消息模式,刷盘方式

    一.Consumer 批量消费(推模式) 可以通过 consumer.setConsumeMessageBatchMaxSize(10);//每次拉取10条 这里需要分为2种情况 Consumer端先 ...

  5. mybatis中如果存在参数不再实体中的是如何处理

    <select id="queryMapByType" parameterType="int" resultType="my.geomap.VO ...

  6. Android——子线程操作主线程

    子线程不能直接操作主线程 UI线程 //水平进度条 public void jdt1_onclick(View view) { final ProgressDialog pd = new Progre ...

  7. JavaScrip——DOM操作(属性操作)

    Attribute a.setAttribute("属性名","属性值")——设置属性 a.getSttribute("属性名")——获取属 ...

  8. cs108 04 oop design

    oop design 分为以下几个方面: - encapsulation and modularity(封装和模块化) - API/Client interface design(API 接口给调用类 ...

  9. matlab 等值线函数 contour

    matlab 等值线函数 contour contour是等高线绘制函数我并没怎么用过这个函数,只是参照help将上面的英文翻译一下,如果有错误,请大家提出来.contour(Z)根据矩阵Z画出等高线 ...

  10. Session和几种状态保持方案理解

    一.术语session 在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含义是相同的. session, ...