在Avalonia中实现MVVM的消息通知,最常用、最轻量且推荐的方式是使用 CommunityToolkit.Mvvm 内置的
WeakReferenceMessenger—— 它就是 Avalonia 社区主流的“Messenger”机制,无需额外安装 MVVM Light 或第三方消息总线。
消息通知的核心:WeakReferenceMessenger
它基于弱引用设计,避免内存泄漏,天然适配 Avalonia + CommunityToolkit.Mvvm 项目结构。关键点:
全局单例:通过WeakReferenceMessenger.Default访问 类型安全:支持泛型消息(如
string、
AlbumViewModel、自定义类) 带 Token 的精准路由:用字符串 token 控制订阅/发送范围,防止误触 自动解注册:View 关闭时,ViewModel 若用
this订阅,会随生命周期自动清理
发送消息(从 ViewModel 出发)
比如点击按钮后通知主窗口刷新列表:
[RelayCommand]
void BuyMusic()
{
if (SelectedAlbum != null)
{
WeakReferenceMessenger.Default.Send(SelectedAlbum, "buyMusic");
}
}
这里
"buyMusic"是 token,后续订阅必须用相同字符串才能收到。
接收消息(在目标 ViewModel 中)
在主窗口 ViewModel 的构造函数里注册监听:
public MainWindowViewModel()
{
// 注册:监听 AlbumViewModel 类型 + "buyMusic" token 的消息
WeakReferenceMessenger.Default.Register<AlbumViewModel, string>(
this,
"buyMusic",
(recipient, message) =>
{
Albums.Add(new AlbumViewModel(message)); // 更新集合
});
}
注意:
this是接收方实例,确保能自动反注册;
Albums是
[ObservableProperty]或手动实现
INotifyCollectionChanged的集合,才能触发 UI 刷新。
进阶用法:跨层或带上下文的通知
如果需要传递更复杂语义(比如操作结果、错误码),可定义专用消息类:
public record OperationResult(bool Success, string Message, object? Data = null);
发送端:
WeakReferenceMessenger.Default.Send(new OperationResult(true, "保存成功", savedItem), "saveCompleted");
接收端只需改泛型类型:
WeakReferenceMessenger.Default.Register<OperationResult, string>(this, "saveCompleted", (_, msg) =>
{
if (msg.Success) ShowNotification(msg.Message, NotificationType.Success);
});
基本上就这些。不复杂但容易忽略的是 token 字符串一致性、泛型类型匹配、以及确保接收方 ViewModel 实例生命周期与注册动作对齐 —— 只要守住这三点,Messenger 就很稳。
