利刃 MVVMLight 9:Messenger

简介: 原文:利刃 MVVMLight 9:Messenger      MVVM的目标之一就是为了解耦View和ViewModel。View负责视图展示,ViewModel负责业务逻辑处理,尽量保证 View.xaml.cs中的简洁,不包含复杂的业务逻辑代码。
原文: 利刃 MVVMLight 9:Messenger

      MVVM的目标之一就是为了解耦View和ViewModel。View负责视图展示,ViewModel负责业务逻辑处理,尽量保证 View.xaml.cs中的简洁,不包含复杂的业务逻辑代码。

但是在实际情况中是View和ViewModel之间的交互方式还是比较复杂的,View和ViewModel的分离并不是界定的那么清晰。

比如以下两种场景:

      1、如果需要某张视图页面弹出对话框、弹出子窗体、处理界面元素,播放动画等。如果这些操作都放在ViewModel中,就会导致ViewModel还是要去处理View级别的元素,造成View和ViewModel的依赖。

最好的办法就是ViewModel通知View应该做什么,而View监听接收到命令,并去处理这些界面需要处理的事情。

      2、ViewModel和ViewModel之间也需要通过消息传递来完成一些交互。 

      而MVVM Light  的 Messenger类,提供了解决了上述两个问题的能力:

Messenger类用于应用程序的通信,接受者只能接受注册的消息类型,另外目标类型可以被指定,用Send<TMessage, TTarget>(TMessage message) 实现,

在这种情况下信息只能被传递如果接受者类型和目标参数类型匹配,message可以是任何简单或者复杂的对象,你可以用特定的消息类型或者创建你自己的类型继承自他们。

Messager类的主要交互模式就是信息接受和发送(可以理解为“发布消息服务”和“订阅消息服务”),是不是想到观察者模式了,哈哈哈。

MVVM Light Messenger 旨在通过简单的设计模式来精简此场景:任何对象都可以是接收端;任何对象都可以是发送端;任何对象都可以是消息。

如图: 

 

 

 

1、View和ViewModel之间的消息交互

在View和ViewModel中进行消息器注册,相当于订阅服务。包含消息标志、消息参数和消息执行方法。如下:

消息标志token:ViewAlert,用于标识只阅读某个或者某些Sender发送的消息,并执行相应的处理,所以Sender那边的token要保持一致

执行方法Action:ShowReceiveInfo,用来执行接收到消息后的后续工作,注意这边是支持泛型能力的,所以传递参数很方便。

View.xaml.cs 代码如下:

 1   public partial class NessagerForView : Window
 2     {
 3         public NessagerForView()
 4         {
 5             InitializeComponent();
 6 
 7             //消息标志token:ViewAlert,用于标识只阅读某个或者某些Sender发送的消息,并执行相应的处理,所以Sender那边的token要保持一致
 8             //执行方法Action:ShowReceiveInfo,用来执行接收到消息后的后续工作,注意这边是支持泛型能力的,所以传递参数很方便。
 9             Messenger.Default.Register<String>(this, "ViewAlert", ShowReceiveInfo);
10             this.DataContext = new MessengerRegisterForVViewModel();
11             //卸载当前(this)对象注册的所有MVVMLight消息
12             this.Unloaded += (sender, e) => Messenger.Default.Unregister(this);
13         }
14 
15         /// <summary>
16         /// 接收到消息后的后续工作:根据返回来的信息弹出消息框
17         /// </summary>
18         /// <param name="msg"></param>
19         private void ShowReceiveInfo(String msg)
20         {
21             MessageBox.Show(msg);
22         }
23     }

 ViewModel代码:

 1  public class MessengerRegisterForVViewModel:ViewModelBase
 2     {
 3 
 4         public MessengerRegisterForVViewModel()
 5         {
 6           
 7         }
 8 
 9         #region 命令
10 
11         private RelayCommand sendCommand;
12         /// <summary>
13         /// 发送命令
14         /// </summary>
15         public RelayCommand SendCommand
16         {
17             get
18             {
19                 if (sendCommand == null)
20                     sendCommand = new RelayCommand(() => ExcuteSendCommand());
21                 return sendCommand;
22 
23             }
24             set { sendCommand = value; }
25         }
26 
27         private void ExcuteSendCommand()
28         {
29             Messenger.Default.Send<String>("ViewModel通知View弹出消息框", "ViewAlert"); //注意:token参数一致
30         }
31 
32         #endregion
33     }

  结果:

 

2、ViewModel和ViewModel之间的消息交互,ViewModel和ViewModel在很多种场景下也需要通过消息传递来完成一些交互。

比如我打开了两个视图,一个视图是用户信息列表,一个视图是用户信息添加页面,如果想要达到添加信息之后,用户信息列表视图实时刷新,用消息通知无疑是一个很棒的体验。

我们来模拟一下:

MessengerRegisterViewModel代码:

 1   public class MessengerRegisterViewModel:ViewModelBase
 2     {
 3         public MessengerRegisterViewModel()
 4         {
 5             ///Messenger:信使
 6             ///Recipient:收件人
 7             Messenger.Default.Register<String>(this,"Message",ShowReceiveInfo);
 8         }
 9 
10 
11         #region 属性
12 
13         private String receiveInfo;
14         /// <summary>
15         /// 接收到信使传递过来的值
16         /// </summary>
17         public String ReceiveInfo
18         {
19             get { return receiveInfo; }
20             set { receiveInfo = value; RaisePropertyChanged(()=>ReceiveInfo); }
21         }
22 
23         #endregion
24 
25 
26         #region 启动新窗口
27 
28         private RelayCommand showSenderWindow;
29 
30         public RelayCommand ShowSenderWindow
31         {
32             get {
33                 if (showSenderWindow == null)
34                     showSenderWindow = new RelayCommand(()=>ExcuteShowSenderWindow());
35                 return showSenderWindow; 
36             
37             }
38             set { showSenderWindow = value; }
39         }
40 
41         private void ExcuteShowSenderWindow()
42         {
43             MessengerSenderView sender = new MessengerSenderView();
44             sender.Show();
45         }
46 
47         #endregion 
48         
49 
50         #region 辅助函数
51         /// <summary>
52         /// 显示收件的信息
53         /// </summary>
54         /// <param name="msg"></param>
55         private void ShowReceiveInfo(String msg)
56         {
57             ReceiveInfo += msg+"\n";
58         }
59         #endregion
60     }

 

 MessengerSenderViewModel代码:

 1  public class MessengerSenderViewModel:ViewModelBase
 2     {
 3         public MessengerSenderViewModel()
 4         {
 5 
 6         }
 7 
 8         #region 属性
 9         private String sendInfo;
10         /// <summary>
11         /// 发送消息
12         /// </summary>
13         public String SendInfo
14         {
15             get { return sendInfo; }
16             set { sendInfo = value; RaisePropertyChanged(()=>SendInfo); }
17         }
18 
19         #endregion
20         
21         #region 命令
22 
23         private RelayCommand sendCommand;
24         /// <summary>
25         /// 发送命令
26         /// </summary>
27         public RelayCommand SendCommand
28         {
29             get
30             {
31                 if (sendCommand == null)
32                     sendCommand = new RelayCommand(() => ExcuteSendCommand());
33                 return sendCommand;
34 
35             }
36             set { sendCommand = value; }
37         }
38 
39         private void ExcuteSendCommand()
40         {
41             Messenger.Default.Send<String>(SendInfo, "Message");
42         }
43 
44         #endregion
45     }

 

 结果如下:

 

下载示例代码

转载请注明出处,谢谢

 

目录
相关文章
|
开发者
苹果又被拒了:Guideline 4.3 - Design
今天来公司,一看,替外公司发布的苹果应用,果然被拒了。被拒原因如下:   Guideline 4.3 - Design   硬着头皮看了一下说明,大意是跟别的应用重复。WHAT?咱这个确实是马甲,可是为别人做的啊。怎么就不能发了?赶紧搜索看看。找到以下资料,发现事情有点麻烦。这个是为其他公司做的马甲包,如果要用申请其他账号就要交钱,那还是等合同之后再说吧。
943 0
|
前端开发 C# 设计模式
利刃 MVVMLight 1:MVVMLight介绍以及在项目中的使用
原文:利刃 MVVMLight 1:MVVMLight介绍以及在项目中的使用 一、MVVM 和 MVVMLight介绍 MVVM是Model-View-ViewModel的简写。类似于目前比较流行的MVC、MVP设计模式,主要目的是为了分离视图(View)和模型(Model)的耦合。
1544 0
|
存储 监控 API
Activity初窥门径
上一节中我们对Activity一些基本的概念进行了了解,什么是Activity,Activity的生命周期,如何去启动一个Activity等,本节我们继续来学习Activity,前面也讲了一个App一般都是又多个Activity构成的,这就涉及到了多个Activity间数据传递的问题了,那么本节继续学习Activity的使用!另外关于传递集合,对象,数组,Bitmap的我们会在Intent那里进行讲解,这里只介绍如何传递基本数据!
67 0
|
C# 开发者 容器
[UWP]合体姿势不对的HeaderedContentControl
原文:[UWP]合体姿势不对的HeaderedContentControl 1. 前言 HeaderedContentControl是WPF中就存在的控件,这个控件的功能很简单:提供Header和Content两个属性,在UI上创建两个ContentPresenter并分别绑定到Header和Content,让这两个ContentPresenter合体组成HeaderedContentControl。
871 0
|
前端开发
[MVVM Light]Messenger 的使用
原文:[MVVM Light]Messenger 的使用 当我们使用MVVM开发模式进行开发时,ViewModel之间的通信常常是很头疼的事情,好在MVVM Light提供了Messenger类可以轻松的在ViewModel之间传递消息。
1241 0
|
调度 Windows
利刃 MVVMLight 10:Messenger 深入
原文:利刃 MVVMLight 10:Messenger 深入 1、Messager交互结构和消息类型 衔接上篇,Messeger是信使的意思,顾名思义,他的目是用于View和ViewModel 以及 ViewModel和ViewModel 之间的消息通知和接收。
1096 0
|
前端开发 C# Windows
利刃 MVVMLight 7:命令深入
原文:利刃 MVVMLight 7:命令深入   上面一篇我们大致了解了命令的基本使用方法和基础原理,但是实际在运用命令的时候会复杂的多,并且会遇到各种各样的情况。 一、命令带参数的情况: 如果视图控件所绑定的命令想要传输参数,需要配置 CommandParameter 属性 ,用来传输参数出去。
854 0
|
前端开发
利刃 MVVMLight 6:命令基础
原文:利刃 MVVMLight 6:命令基础     在MVVM Light框架中,事件是WPF应用程序中UI与后台代码进行交互的最主要方式,与传统方式不同,mvvm中主要通过绑定到命令来进行事件的处理, 因此要了解mvvm中处理事件的方式,就必须先熟悉命令的工作原理。
1023 0
|
前端开发 索引 API
利刃 MVVMLight 5:绑定在表单验证上的应用
原文:利刃 MVVMLight 5:绑定在表单验证上的应用    表单验证是MVVM体系中的重要一块。而绑定除了推动 Model-View-ViewModel (MVVM) 模式松散耦合 逻辑、数据 和 UI定义 的关系之外,还为业务数据验证方案提供强大而灵活的支持。
778 0
|
开发者
[UWP]了解模板化控件(2):模仿ContentControl
原文:[UWP]了解模板化控件(2):模仿ContentControl ContentControl是最简单的TemplatedControl,而且它在UWP出场频率很高。ContentControl和Panel是VisualTree的基础,可以说几乎所有VisualTree上的UI元素的父节点中总有一个ContentControl或Panel。
1073 0