WPF的MVVM框架Stylet开发文档 8.事件聚合器EventAggregator

8.事件聚合器EventAggregator

原文地址

事件聚合器是一个分散的、弱绑定的、基于发布/订阅的事件管理器。

发布者和订阅者

订户

对特定事件感兴趣的订阅者可以告诉 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

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

退订和弱绑定(Unsubscribing and weak binding)

因为 IEventAggregator 是弱绑定的,订阅者不需要自己取消订阅 - IEventAggregator 不会保留它们。但是,订阅者可以根据需要自行取消订阅 - 调用

C#
IEventAggregator.Unsubscribe(this);

同步和异步发布

默认IEventAggregator.Publish方法同步发布事件。您还可以调用PublishOnUIThread异步调度到 UI 线程,或者PublishWithDispatcher传递您想要充当调度程序的任何操作(如果在 IEventAggregator 上编写自己的方法,这可能很有用)。

通道Channels

订阅者可以收听特定的通道,而发布者可以将事件发布到特定的通道。如果将事件发布到特定通道,则只有订阅该通道的订阅者才会收到该事件。如果在几个不同的上下文中使用相同的消息类型,这将很有用。

通道是字符串,因此允许通道的订阅者和该通道的发布者之间松散耦合。

默认情况下,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)将取消您对所有通道的订阅。

使用自己的 IoC 容器

如果您将 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

你可能感兴趣的:(MVVM,Stylet框架,wpf,ui,c#)