为了应用程序的不同模块分离,减少模块之间引用,CommunityToolkit.Mvvm提供了消息通知功能,可以方便模块之间数据传递。
方法:WeakReferenceMessenger.Default.Send
官方推荐用ValueChangedMessage封装数据传递
//Send发送消息 WeakReferenceMessenger.Default.Send<string>( "qq1" ); //特别注意:直接传递值,只可以是引用类型,值类型不可以编译成功的(例如:下面2句不行) //WeakReferenceMessenger.Default.Send<int , string>( 11 , "token_1" ); //WeakReferenceMessenger.Default.Send<bool , string>( true , "token_1" ); //上面这样也是可以的,但是官方推荐用ValueChangedMessage封装数据传递 WeakReferenceMessenger.Default.Send<ValueChangedMessage<string> , string>( new ValueChangedMessage<string>( "UserControlLeftViewModel发来的qq1" ) , "token_1" );
建议发送消息时都带上token名称,这样方便订阅接收方过滤数据
WeakReferenceMessenger.Default.Send<ValueChangedMessage<string> , string>( new ValueChangedMessage<string>( "UserControlLeftViewModel发来的qq1" ) , "token_1" );
public class MyUserMessage { public string UserName { get; set; } public int Age { get; set; } }
//Send发送 一个复杂数据 var _data1 = new MyUserMessage() { Age = 18 , UserName = "qq" }; WeakReferenceMessenger.Default.Send<ValueChangedMessage<MyUserMessage> , string>( new ValueChangedMessage<MyUserMessage>( _data1 ) , "token_class" );
/// <summary> /// 必须继承RequestMessage RequestMessage<string>代表返回数据的类型是string /// </summary> public class MyMessage : RequestMessage<string> { public string Datas; public int Ids; }
//result接收返回的值 //MyMessage这个类必须继承RequestMessage var _data2 = new MyMessage() { Datas = "qqq" , Ids = 100 }; var result1 = WeakReferenceMessenger.Default.Send<MyMessage , string>( _data2 , "token_Response" ); if ( result1 != null ) { //获取到 返回的值 var val = result1.Response; Name = val; }
接收2种方式:
方式1.继承ObservableRecipient
方式2.实现接口IRecipient
方式1比方式2灵活,推荐使用方式1
接收方记得设置IsActive=true,才可以收到消息
我们在vm的OnActivated中接收消息数据
[ObservableProperty] private string name = "hello"; public UserControlTopViewModel () { //注意这样要写,才可以接听 IsActive = true; }
protected override void OnActivated () { //Register<>第一个类型一般是自己的类型,第2个是接收数据的类型 //Register方法第1个参数一般是this,第2个参数是一个方法,可以获取接收到的值 Messenger.Register<UserControlTopViewModel , string>( this , ( r , message ) => { Name = Name + " 收到msg:" + message; } ); //Register<>第一个类型一般是自己的类型,第2个是接收数据的类型,第3个是token数据的类型 //Register方法第1个参数一般是this,第2个参数是token,第3个参数是一个方法,可以获取接收到的值 //Messenger.Register<UserControlTopViewModel , string , string>( this , "token_1" , ( r , message ) => //{ // Name = Name + " 收到msg:" + message; //} ); //ValueChangedMessage<string> Messenger.Register<UserControlTopViewModel , ValueChangedMessage<string> , string>( this , "token_1" , ( r , message ) => { Name = Name + " 收到msg:" + message.Value; } ); //Messenger.Register<UserControlTopViewModel , MyUserMessage , string>( this , "token_class" , ( r , user ) => //{ // Name = Name + " 收到msg:" + user.UserName + user.Age; //} ); Messenger.Register<UserControlTopViewModel , ValueChangedMessage<MyUserMessage> , string>( this , "token_class" , ( r , user ) => { Name = Name + " 收到msg:" + user.Value.UserName + user.Value.Age; } ); Messenger.Register<UserControlTopViewModel , MyMessage , string>( this , "token_Response" , ( r , message ) => { Name = Name + " 收到msg:" + message.Datas; //Reply是答复 ,这样可以返回值 message.Reply( "UserControlTopViewModel给你返回值" ); } ); }
自我Demo地址:
https://github.com/aierong/WpfDemo/tree/main/WpfDemoNet6/MessengerDemo