ObservableRecipient与ObservableObject
在 MVVM(Model-View-ViewModel) 框架中,ObservableObject
和 ObservableRecipient
是 CommunityToolkit.Mvvm
(原名 Microsoft.Toolkit.Mvvm
)提供的两个基类,用于实现数据绑定和消息传递。以下是它们的核心区别与用法:
1. ObservableObject
作用
-
基础实现 INotifyPropertyChanged,用于通知 UI 属性变更(数据绑定)。
-
核心方法:
SetProperty
、OnPropertyChanged
。
典型用法
using CommunityToolkit.Mvvm.ComponentModel;public class UserViewModel : ObservableObject
{private string _name;public string Name{get => _name;set => SetProperty(ref _name, value); // 自动触发 PropertyChanged}
}
特点
-
轻量级:仅处理属性变更通知。
-
手动触发:需要显式调用
SetProperty
或OnPropertyChanged
。
2. `ObservableRecipient
作用
-
继承自
ObservableObject
,额外支持消息传递(IMessenger
模式)。 -
核心功能:
-
继承
ObservableObject
的所有能力。 -
内置
IMessenger
支持(跨 ViewModel 通信)。 -
提供
IsActive
模式(控制消息订阅的生命周期)。
-
典型用法
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;public class UserViewModel : ObservableRecipient
{private string _name;public string Name{get => _name;set => SetProperty(ref _name, value);}protected override void OnActivated(){// 注册接收消息(当 ViewModel 激活时)Messenger.Register<UserUpdatedMessage>(this, (r, m) =>{Name = m.NewName;});}protected override void OnDeactivated(){// 清理消息注册(当 ViewModel 销毁时)Messenger.Unregister<UserUpdatedMessage>(this);}
}
特点
-
消息传递:通过
IMessenger
实现松耦合通信(如跨页面的数据更新)。 -
生命周期控制:通过
IsActive
管理消息订阅的激活/销毁。 -
依赖
IMessenger
:需在 DI 容器中注册WeakReferenceMessenger.Default
。
3. 关键差异对比
特性 | ObservableObject | ObservableRecipient |
---|---|---|
基类功能 | 仅实现 INotifyPropertyChanged | 继承 ObservableObject ,额外支持消息传递 |
消息机制 | 不支持 | 内置 IMessenger (WeakReference 模式) |
生命周期控制 | 无 | 通过 IsActive 管理消息订阅 |
适用场景 | 简单数据绑定 | 跨 ViewModel 通信或复杂状态管理 |
4. 如何选择?
使用 ObservableObject
当:
-
只需要 属性变更通知(如绑定文本框到
string
属性)。 -
不涉及跨组件通信。
使用 ObservableRecipient
当:
-
需要 多个 ViewModel 之间通信(如发送“用户已登录”事件)。
-
需要 自动管理消息订阅的生命周期(避免内存泄漏)。
5. 完整示例:消息传递场景
步骤 1:定义消息类型
public class UserLoggedInMessage
{public string Username { get; set; }
}
步骤 2:发送消息的 ViewModel
public class LoginViewModel : ObservableRecipient
{public void Login(string username){Messenger.Send(new UserLoggedInMessage { Username = username });}
}
步骤 3:接收消息的 ViewModel
public class DashboardViewModel : ObservableRecipient
{private string _welcomeMessage;public string WelcomeMessage{get => _welcomeMessage;set => SetProperty(ref _welcomeMessage, value);}protected override void OnActivated(){Messenger.Register<UserLoggedInMessage>(this, (r, m) =>{WelcomeMessage = $"Welcome, {m.Username}!";});}
}
6. 性能与注意事项
-
ObservableRecipient
更重:因包含消息系统,适合复杂场景。 -
避免过度使用消息:简单数据流直接用属性绑定即可。
-
IsActive
的用途:-
当 ViewModel 绑定到 UI 时(如页面加载),
IsActive = true
激活消息订阅。 -
当 UI 卸载时(如页面关闭),
IsActive = false
自动清理订阅。
-
通过合理选择基类,可以平衡代码的简洁性和功能性。对于大多数 MVVM 应用,ObservableObject
足够;跨组件通信时再升级到 ObservableRecipient
。