ObservableRecipient与ObservableObject

发布于:2025-06-07 ⋅ 阅读:(22) ⋅ 点赞:(0)

在 MVVM(Model-View-ViewModel) 框架中,ObservableObject 和 ObservableRecipient 是 CommunityToolkit.Mvvm(原名 Microsoft.Toolkit.Mvvm)提供的两个基类,用于实现数据绑定和消息传递。以下是它们的核心区别与用法:


1. ObservableObject

作用
  • 基础实现 INotifyPropertyChanged,用于通知 UI 属性变更(数据绑定)。

  • 核心方法:SetPropertyOnPropertyChanged

典型用法
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


网站公告

今日签到

点亮在社区的每一天
去签到