Prism_04_EventAggregator

在 MVVM 中,对于 View 和 ViewModel 之间的交互,可以使用 INotifyProperty 和 ICommand 来实现。而对于不同 ViewModel 之间的通信,为了实现低耦合,Prism 提供了 EventAggregator

EventAggregator 是基于事件聚合器服务,允许发布者和订阅者之间通过事件进行通讯,且彼此之间没有直接引用。

IEventAggregator

EventAggregator 类在容器中是作为服务提供的,其对应的接口是 IEventAggregator.事件管理器用来定位和创建事件,其内部维护系统事件的集合。

public interface IEventAggregator
{
    TEventType GetEvent<TEventType>() where TEventType : EventBase;
}

发布事件

// 定义事件
public class TickerSymbolSelectedEvent : PubSubEvent<string>{}

// 发布者从 EventAggregator 中检索事件并调用 Publish 方法来发布事件
public class MainPageViewModel
{
    IEventAggregator _eventAggregator;
    public MainPageViewModel(IEventAggregator ea)
    {
        _eventAggregator = ea;
    }

    public void PublishEvent()
    {
        // 发布事件,然后拍拍屁股走人,不用负任何责任
        _eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish("STOCK0");
    }
}

订阅事件

public class MainPageViewModel
{
    public MainPageViewModel(IEventAggregator ea)
    {
        ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews);
    }

    void ShowNews(string companySymbol)
    {
        //implement logic
    }
}

订阅者在订阅事件的时候,可以根据不同需求来适当调整接收参数:

  • 线程调度 - 如果收到事件时需要更新UI元素,可以配置接收方法在UI线程上执行
  • 事件过滤 - 可以在订阅时提供过滤委托来过滤事件
  • 强引用 - 如果对事件有性能问题,可以在订阅时使用强引用委托,然后手动取消
  • 默认 - 如果上述都不适用,请使用默认订阅
订阅UI线程

默认情况下,订阅者在发布者的线程上接收事件。如果订阅者需要更新UI元素,在WPF中只有UI线程才可以更新UI元素,需要在订阅时指定线程。

public MainPageViewModel(IEventAggregator ea)
{
    ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread);
}

参数 ThreadOption 还有其他可选项:

  • PublisherThread - 默认值,在发布者线程上接收事件
  • BackgroundThread - 在线程池上接收事件
  • UIThread - 在UI线程上接收事件
过滤事件

通常,订阅者不需要处理发布事件的每个实例,这时候需要订阅者使用过滤参数。

public class MainPageViewModel
{
    public MainPageViewModel(IEventAggregator ea)
    {
        TickerSymbolSelectedEvent tickerEvent = ea.GetEvent<TickerSymbolSelectedEvent>();
        // 通常,此过滤器作为 lambda 表达式;false表示不是强引用
        tickerEvent.Subscribe(ShowNews, ThreadOption.UIThread, false, 
                              companySymbol => companySymbol == "STOCK0");
    }

    void ShowNews(string companySymbol)
    {
        //implement logic
    }
}

强委托引用

如果在短时间内引发多个事件并担心性能问题,可以指定强委托引用。

  • true - 事件实例保持对订阅者实例的强引用,不允许订阅者被垃圾回收
  • false - 默认值,当订阅者被垃圾回收时,该事件自动取消订阅

退订事件

public class MainPageViewModel
{
    TickerSymbolSelectedEvent _event;
    public MainPageViewModel(IEventAggregator ea)
    {
        _event = ea.GetEvent<TickerSymbolSelectedEvent>();
        _event.Subscribe(ShowNews);
    }

    void Unsubscribe()
    {
        _event.Unsubscribe(ShowNews);
    }

    void ShowNews(string companySymbol)
    {
        //implement logic
    }
}

我的公众号 HelloPragram

posted @   RisingWaves  阅读(84)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示