移动端开发:如何用CommunityToolkit.MVVM替代.NET MessagingCenter?
将MessagingCenter迁移至CommunityToolkit.MVVM的实现方案
我将移动端应用从Xamarin迁移到MAUI后,收到提示称MessagingCenter已被弃用,需改用CommunityToolkit.MVVM。已安装该工具包,但代码转换时遇到问题。
原MessagingCenter代码
public Command MgmtCommand { get { return new Command((Vacation vacation) => { //Unsubscribe from events - precautionary step to ensure that there are no existing subscriptions for the specified events MessagingCenter.Unsubscribe(this, "AddVacation"); MessagingCenter.Unsubscribe(this, "UpdateVacation"); //Navigate to the VacationAddView, passing a vacation if available Application.Current.MainPage.Navigation.PushAsync(new VacationMgmtView(vacation)); //Subscribe to a MessagingCenter event for refreshing data when a new vacation is added MessagingCenter.Subscribe<Vacation>(this, "AddVacation", async (data) => { //Refresh the vacation list data asynchronously await RefreshVacationListData(); //Unsubscribe from the MessagingCenter event after refreshing data MessagingCenter.Unsubscribe<Vacation>(this, "AddVacation"); }); //Subscribe to a MessagingCenter event for refreshing data when a new vacation is updated MessagingCenter.Subscribe<Vacation>(this, "UpdateVacation", async (data) => { // Refresh the vacation list data asynchronously await RefreshVacationListData(); // Unsubscribe from the MessagingCenter event after refreshing data MessagingCenter.Unsubscribe<Vacation>(this, "UpdateVacation"); }); }); } }
当前尝试的错误代码
private async Task NavigateAndHandleAddUpdateAsync() { WeakReferenceMessenger.Default.Register<OpenWindowMessage>(this, HandleOpenWindowMessage); } private async Task HandleOpenWindowMessage(object recipient, OpenWindowMessage message) { switch (message.Value) { case true: Application.Current.MainPage.Navigation.PushAsync(new VacationMgmtView(vacation)); break; default: //await DisplayAlert("Alert", "Secondary window was closed", "OK"); break; } }
迁移后的正确实现
1. 定义强类型消息类
CommunityToolkit.MVVM的WeakReferenceMessenger依赖强类型消息,需先创建对应消息类:
using CommunityToolkit.Mvvm.Messaging.Messages; // 对应添加假期的消息 public class AddVacationMessage : ValueChangedMessage<Vacation> { public AddVacationMessage(Vacation value) : base(value) { } } // 对应更新假期的消息 public class UpdateVacationMessage : ValueChangedMessage<Vacation> { public UpdateVacationMessage(Vacation value) : base(value) { } }
2. 重构MgmtCommand代码
替换原MessagingCenter逻辑为WeakReferenceMessenger的实现:
using CommunityToolkit.Mvvm.Messaging; public Command MgmtCommand { get { return new Command(async (Vacation vacation) => { // 预先取消现有订阅,避免重复监听 WeakReferenceMessenger.Default.Unregister<AddVacationMessage>(this); WeakReferenceMessenger.Default.Unregister<UpdateVacationMessage>(this); // 导航到假期管理页面 await Application.Current.MainPage.Navigation.PushAsync(new VacationMgmtView(vacation)); // 订阅添加假期完成的消息 WeakReferenceMessenger.Default.Register<AddVacationMessage>(this, async (recipient, message) => { await RefreshVacationListData(); // 处理完成后取消订阅 WeakReferenceMessenger.Default.Unregister<AddVacationMessage>(recipient); }); // 订阅更新假期完成的消息 WeakReferenceMessenger.Default.Register<UpdateVacationMessage>(this, async (recipient, message) => { await RefreshVacationListData(); // 处理完成后取消订阅 WeakReferenceMessenger.Default.Unregister<UpdateVacationMessage>(recipient); }); }); } }
3. 在VacationMgmtView中发送消息
当假期添加或更新操作完成后,在对应的ViewModel中发送消息:
// 添加假期完成时发送消息 WeakReferenceMessenger.Default.Send(new AddVacationMessage(addedVacation)); // 更新假期完成时发送消息 WeakReferenceMessenger.Default.Send(new UpdateVacationMessage(updatedVacation));
错误代码问题说明
你之前的尝试存在以下问题:
- 使用了不匹配业务逻辑的
OpenWindowMessage,未对应原代码中的Add/Update事件 - 未遵循原逻辑中的订阅时机(导航后订阅)和一次性订阅(处理后取消)的设计
- 缺少强类型消息的定义,导致消息传递逻辑无法和原功能对齐
内容的提问来源于stack exchange,提问作者CipherIS
相关产品推荐
相关产品推荐

