文章目录
环境
CommunityToolkit.Mvvm Messenger
十月的寒流: 如何使用 CommunityToolkit.Mvvm 中的 Messenger 来进行 ViewModel 之间的通信
WeakReferenceMessenger
我这里只讲简单的弱Messenger,这个是Toolkit帮我们封装好的,里面好像有什么垃圾回收什么的,里面怎么运行的我也没去研究。我这里就简单讲解一下怎么用
方法介绍
- WeakReferenceMessenger.Default.Register
- 订阅消息
- WeakReferenceMessenger.Default.Send
- 接收消息
为了保证一对一,我们注册和发送的时候需要用到record结构体==(我后面试了一下,当然也可以不用,单纯一个类也行)==。因为这个是根据type的name来进行订阅和发送的。
C# 9.0:Records 结构体介绍
无回调订阅发送
csharp
//声明record
//类型可以自定义,是通过record的类名自动订阅和发送的
public record LogMessage(string msg);
///在viewModel里面订阅
public partial class ListViewModel
{
public ListViewModel()
{
//在构造函数里面订阅。注意订阅一定是你接受的消息类型
//第一个是订阅者,默认是本身,就是this
WeakReferenceMessenger.Default.Register<LogMessage>(this, Recive);
}
//recipient 就是把订阅者,也就是ViewModel传给你,一般用不上
//第二个参数是你的Recive的值
public void Recive(object recipient, LogMessage msg)
{
Debug.WriteLine("ListViewModel:" + msg.msg);
}
}
发送
csharp
//发送和接受的类型一定是一致的
WeakReferenceMessenger.Default.Send<LogMessage>(new LogMessage("lala"));
Token区分
WeakReferenceMessenger.Default.Register<TMessage,Ttoken>
在里面可以传入两个泛型
csharp
//订阅
WeakReferenceMessenger.Default.Register<LogMessage,string>(this,"token", Recive);
//发送
//注意,这里的token必须完全一致
WeakReferenceMessenger.Default.Send<LogMessage,string>(new LogMessage("发送信息"),"token");
这里Token建议使用enum枚举类型,方便静态编译和纠错
有回调订阅发送
如果要添加回调功能,需要ViewModel继承IRecipient<RequestMessage<TMessage>>接口,TMessage和上面一样,都是订阅对象
csharp
public partial class LogViewModel : ObservableObject,IRecipient<RequestMessage<LogMessage>>
{
[ObservableProperty]
private string title = "控制台界面";
public LogViewModel()
{
//接口必须实现
WeakReferenceMessenger.Default.Register(this);
}
//消息返回
public void Receive(RequestMessage<LogMessage> message)
{
Debug.WriteLine("我接受到了消息"+ message.Response.msg);
message.Reply(new LogMessage("我返回的消息"));
}
}
但是感觉并不是很好用,因为这样就没有Token了,而且回调的类型和传入的类型是一致的,这个太死板了,可以通过record里面定义一个Action去回调,这里不展开说明
csharp
public record LogMessage(string msg,Action<string> callback);