Messenger
使用这个可以解耦业务代码和视图之间的强引用。在注册之后,只有使用同一种令牌发送消息,才会触发事件来执行对应的方法。
// // 摘要: //为某种类型的消息 TMessage 注册一个接收者。 当发送相应的消息 //时,将执行 action 参数。 有关如何接收从 TMessage 派生的消息 //(或者,如果 TMessage 是接口,则实现 TMessage 的消息)的详 //细信息,请参阅 receiveDerivedMessagesToo 参数。 注册接收者 //不会创建对它的硬引用,因此如果删除此接收者,则不会导致内存泄漏。 // // 参数: // recipient: // 将接收消息的收件人。 // // token: 消息通道的令牌。 // 如果收件人使用令牌注册,并且 // 发送者使用相同的令牌发送一条消息,然后这条消息将被传递 // 给收件人。 注册时未使用令牌的其他接收者(或 // 谁使用了不同的令牌)将不会收到消息。 同样,发送的消息 // 没有任何令牌,或使用不同的令牌,将不会传递给该接收者。 // // action:发送 TMessage 类型的消息时将执行的操作。 // // 保持目标活着: // 如果为 true,则 Action 的目标将作为硬引用保留,这可能 // 导致内存泄漏。 如果操作,您应该只将此参数设置为 true // 正在使用闭包。 请参阅 http://galasoft.ch/s/mvvmweakaction。 // // 类型参数: // TMessage: // 收件人注册的消息类型。 void Register<TMessage>(object recipient, object token, Action<TMessage> action, bool keepTargetAlive = false);
示例:
后台:
namespace MyWpf { /// <summary> /// MyMessenger.xaml 的交互逻辑 /// </summary> public partial class MyMessenger : UserControl { public MyMessenger() { InitializeComponent(); this.DataContext = new BussinessLayer(); //第一步:注册 //接收人为当前控件,令牌为TestToken,执行方法为GetData Messenger.Default.Register<string>(this, "TestToken", GetData); } /// <summary> /// 第三步:处理接收到的信息 /// </summary> /// <param name="obj"></param> private void GetData(string obj) { MessageBox.Show(obj); } } /// <summary> /// 一个测试的业务层 /// </summary> public class BussinessLayer { public BussinessLayer() { Open = new RelayCommand(Test) ; } public RelayCommand Open { get; set; } private void Test() { //第二步:向令牌为TestToken的Messenger发送信息 Messenger.Default.Send("测试Messenger", "TestToken"); } } }
xaml:
<UserControl x:Class="MyWpf.MyMessenger" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:MyWpf" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Button Command="{Binding Open}" Content="测试" Width="200" Height="100"></Button> </Grid> </UserControl>
效果: