原文地址
事件聚合器是一个分散的、弱绑定的、基于发布/订阅的事件管理器。
对特定事件感兴趣的订阅者可以告诉 IEventAggregator 他们感兴趣,并且只要发布者将该特定事件发布到 IEventAggregator,就会收到通知。
事件就是类 - 对它们做任何你想做的事情。例如:
class MyEvent {
// Do something
}
订阅者必须实现IHandle,T他们有兴趣接收的事件类型在哪里(他们当然可以为多个IHandle实现多个 T)。然后他们必须获取 IEventAggregator 的一个实例,并订阅自己,例如:
class Subscriber : IHandle<MyEvent>, IHandle<MyOtherEvent>
{
public Subscriber(IEventAggregator eventAggregator)
{
eventAggregator.Subscribe(this);
}
public void Handle(MyEvent message)
{
// ...
}
public void Handle(MyOtherEvent message)
{
// ...
}
}
对于 VB.NET 用户,Sub New()通过引用传递 eventAggregator 可能会在命名空间中失败,并且必须为每个新订阅者定义可能会很烦人。因此,在全局模块中定义 eventAggregator 可能更容易,然后直接订阅它,而不是将其引用传递给您调用的每个新 ViewModel。
Module Global
Public eventAggregator as IEventAggregator
End Module
Class Subscriber : Implements IHandle(Of MyEvent)
Public Sub New()
Global.eventAggregator.Subscribe(Me)
End Sub
'Public Sub Handle...
End Class
确保将模块的命名空间保留为空白,以便它可以在整个程序中使用。
Publishers(发布者)还必须获得 IEventAggregator 的实例,但他们不需要自己订阅 - 他们只需要在每次想要发布事件时调用 IEventAggregator.Publish,例如:
class Publisher
{
private IEventAggregator eventAggregator;
public Publisher(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
public void PublishEvent()
{
this.eventAggregator.Publish(new MyEvent());
}
}
同样,对于 VB.NET 用户,如果您设置了全局模块,那么您不需要将 eventAggregator 传递给 Publisher。您可以直接发布到全局事件聚合器;
Class Publisher
Public Sub PublishEvent()
Global.eventAggregator.Publish(New MyEvent())
End Sub
End Class
因为 IEventAggregator 是弱绑定的,订阅者不需要自己取消订阅 - IEventAggregator 不会保留它们。但是,订阅者可以根据需要自行取消订阅 - 调用
C# |
---|
IEventAggregator.Unsubscribe(this); |
默认IEventAggregator.Publish方法同步发布事件。您还可以调用PublishOnUIThread异步调度到 UI 线程,或者PublishWithDispatcher传递您想要充当调度程序的任何操作(如果在 IEventAggregator 上编写自己的方法,这可能很有用)。
订阅者可以收听特定的通道,而发布者可以将事件发布到特定的通道。如果将事件发布到特定通道,则只有订阅该通道的订阅者才会收到该事件。如果在几个不同的上下文中使用相同的消息类型,这将很有用。
通道是字符串,因此允许通道的订阅者和该通道的发布者之间松散耦合。
默认情况下,Subscribe()
将为订阅者订阅单个通道,EventAggregator.DefaultChannel
. 同样,Publish()
(及其所有变体)会将事件发布到相同的默认通道。但是,您可以根据需要指定自己的通道…
要订阅特定通道,请将其作为参数传递给Subscribe: eventAggregator.Subscribe(this, "ChannelA")
。您还可以订阅多个通道:eventAggregator.Subscribe(this, "ChannelA", "ChannelB")
。
在这两种情况下,您都不会订阅EventAggregator.DefaultChannel
只会订阅列出的通道。您只会收到推送到“ChannelA”或“ChannelB”的事件。
要发布到特定通道,请将其作为参数传递给Publish:eventAggregator.Publish(message, "ChannelA")
或eventAggregator.PublishOnUIThread(message, "ChannelA", "ChannelB")
等。与上面的订阅一样,事件将发布到所有指定的通道,而不是默认通道。
要取消订阅通道,请将其传递给Unsubscribe: eventAggregator.Unsubscribe(this, "ChannelA")
。您将继续订阅您之前订阅的任何其他通道,并且尚未取消订阅。
使用eventAggregator.Unsubscribe(this)
将取消您对所有通道的订阅。
如果您将 StyletIoC 与 default 一起使用Bootstrapper
,则无需担心这一点 - EventAggregator 默认设置正确。
但是,如果您正在使用另一个 IoC 容器,则需要确保 EventAggregator 已注册为接口的单例服务IEventAggregator
- 必须永远只创建一个 EventAggregator 实例,并且必须每次返回这个实例请求的时间。
项目原地址:https://github.com/canton7/Stylet
当前文档原地址:https://github.com/canton7/Stylet/wiki/The-EventAggregator
上一篇:WPF的MVVM框架Stylet开发文档 7. 消息框MessageBox
下一篇:WPF的MVVM框架Stylet开发文档 9. 属性变化推送基类PropertyChangedBase