Event Aggregator,有趣的设计约束

时间:2011-10-04 10:38:22

标签: wpf prism

我最近遇到的一个非常有趣的问题(或设计约束)。

我正在开发使用WPF / Prism构建的应用程序。

此应用程序的一个功能(非常紧迫的客户端要求)是打开表单的多个重复视图(比如多个客户输入表单)。我们正在使用MVVM模式,因此我们有多个VM对象驻留在内存中。

现在,我们的一个服务部门发布了事件,我们的虚拟机订阅了它,因此所有打开的视图模型都获得了事件通知和状态执行代码。

现在我们的问题是限制它,实际上只有VM应该开始执行实际启动操作的代码。

我认为,这个问题也会出现在正常事件中,而且它实际上正在做的事情要通知所有的列表。

我们已经检查以确定哪个VM在获取通知后仅启动操作VM shd执行代码的操作。

我的问题是,在这种非常罕见的情节中,正确的设计应该是什么?

2 个答案:

答案 0 :(得分:2)

我们有一个类似于你所描述的场景,我们解决了这个'问题',让发起操作的视图在请求中发送一个唯一的id(Guid),响应请求的后台服务正在发送除了数据具有相同的唯一ID。

上面的场景将能够过滤每个视图的事件聚合器由后台服务发布的事件。

 Guid referenceGuid = Guid.NewGuid();

//Subscribe to the futures events which are being published by the background service (filter per referenceGuid).
_eventAggregator.GetEvent<RetrieveMetricsResponseEvent>().Subscribe(ProcessUpdates, ThreadOption.BackgroundThread, true, response => response.ReferenceId == referenceGuid);



// Send the request to the background service
_eventAggregator.GetEvent<RetrieveMetricsRequestEvent>().Publish(new WrappedRetrieveMetricsRequest { MetricSourceID = configuration.StrategyInstanceCode, Identifier = configuration.SourceValueFieldName, ReferenceId = referenceGuid });

答案 1 :(得分:1)

通常我将参数附加到EventMessage,它定义了哪个ViewModel应该处理事件。如果该值可以为null(意味着任何VM都可以处理它),我经常向EventMessage添加Handled属性,并且第一个ViewModel处理事件集eventParams.Handled = true

例如,要将事件发布到同一个VM,我会使用如下语法:

// Publish for specific ViewModel
eventAggregator.GetEvent<MyMessage>().Publish(
    new MyEventArgs { SpecifiedViewModel = this });

// Publish for any ViewModel
eventAggregator.GetEvent<MyMessage>().Publish(
    new MyEventArgs());

要处理一个只应由一个ViewModel处理的事件,代码可能如下所示:

void HandleEvent(MyEventArgs e)
{
    if ((SpecifiedViewModel == null && !(e.Handled))
     || (SpecifiedViewModel == this))
    {
        // Handle Event
        e.Handled == true;
    }
}