在 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
。