一、ObservableRecipient
1.1. 定义
所处的位置,
命名控件:Microsoft.Toolkit.Mvvm.ComponentModel
程序集:Microsoft.Toolkit.Mvvm.dll
包:Microsoft.Toolkit.Mvvm
ObservableRecipient类型是可监视对象(Observable objects)的一个基类,这些对象扮演着消息接收者的角色。ObservableRecipient类是ObservableObject的拓展,它也提供了使用IMessenger类型的内置支持。
继承关系:
Object→ObservableObject→ObservableRecipient
相关的平台API:
- ObservableRecipient
- ObservableObject
- IMessenger
- WeakReferenceMessenger
- IRecipient<TMessage>
- PropertyChangedMessage<T>
1.2. 它是如何工作的
ObservableRecipient设计出来是用来作为viewmodel的基础(或者说基对象)的,它也使用了IMessenger的特性,因为它为IMessenger提供了内置支持。特别地:
- 它有一个无参的构造函数和一个接受IMessenger实例的构造函数,被用作依赖注入。
它还暴露了一个Messenger属性,可用来在viewmodel中收发消息。如果使用了无参构造函数,WeakReferenceMessenger.Default实例将会被分配给Messenger属性。 - 它暴露了IsActive属性以激活(Activate)/禁用(Deactivate)viewmodel。在这种情况下,激活意味着viewmodel被标记为正在使用,例如,它将开始监听已注册的消息,执行其他的设置操作等。有两个相关的方法OnActivated 和 OnDeactivated,在属性改变值时,它们会被调用。默认情况下,OnDeactivated会自动从所有已注册的消息中注销当前实例。为了获得最佳效果和避免内存泄漏,建议使用OnActivate来注册消息,使用OnDeactivate来做清理操作。这种模式允许viewmodel启停多次,同时可以安全地收集,而不会在每次停用的时候产生内存泄漏的风险。默认情况下,OnActivate会自动注册所有通过IRecipient<TMessage>接口定义的消息处理器。
- 它暴露了Broadcast<T>(T, T, string)方法,该方法通过IMessenger实例(可以从Messenger属性获得)发送PropertyChangedMessage<T>消息。这可以用来轻松传播viewmodel中的变化,而不需要手动地检索Messenger实例来使用。该方法通过各种SetProperty方法的重载来使用,这些方法还有一个附加的bool broadcast属性,用于指示是否也发送消息。
下面有一个viewmodel的示例,它在激活时接收LoggedInUserRequestMessage 消息:
public class MyViewModel : ObservableRecipient, IRecipient<LoggedInUserRequestMessage>
{
public void Receive(LoggedInUserRequestMessage message)
{
// 处理消息的代码
}
}
在以上例子中,OnActivated自动注册实例作为LoggedInUserRequestMessage 消息的接收者,使用该方法作为要调用的动作。使用IRecipient<TMessage>接口并不是强制的,注册也可以手动完成(甚至只使用内联lambda表达式):
public class MyViewModel : ObservableRecipient
{
protected override void OnActivated()
{
// Using a method group...
Messenger.Register<MyViewModel, LoggedInUserRequestMessage>(this, (r, m) => r.Receive(m));
// ...or a lambda expression
Messenger.Register<MyViewModel, LoggedInUserRequestMessage>(this, (r, m) =>
{
// Handle the message here
});
}
private void Receive(LoggedInUserRequestMessage message)
{
// Handle the message here
}
}