2011-10-04 24 views
1

最近我遇到了一個非常有問題的問題(或設計約束)。事件聚合器,有趣的設計約束

我正在開發一個使用WPF/Prism構建的應用程序。

和特徵(非常緊迫的客戶要求)的這個程序是打開窗體的多個重複的畫面之一(說多客戶的報名表)。我們使用MVVM模式,因此我們有多個駐留在內存中的VM對象。

現在我們的服務的一個引發事件的發佈,我們的虛擬機訂閱它,因此,所有打開的視圖模型得到了事件通知和statrs執行代碼。

現在這裏在於我們的問題來限制這個,實際上只有VM應該開始執行其實際啓動操作碼。

我認爲,這個問題將與正常事件一樣,並且它實際上是在做有意義的事情來通知所有列表者。

我們已經通過檢查來確定哪個VM啓動操作,只有在獲取通知後虛擬機shd執行代碼。

我的問題是,在這個非常罕見的場景中應該是正確的設計?

+0

我不認爲這是在罕見的情況下所有。我正在做同樣的事情。多份。我還需要正確導航並將這些視圖顯示爲「標籤」。我沒有解決你在談論的問題,但我的想法和米歇爾一樣。爲每個視圖指定一個Guid,並在訂閱/過濾事件時使用它。 – katit

回答

2

我們有simular情況下,你所描述的,我們解決了這個「問題」,讓該啓動操作請求發送一個唯一的ID(GUID)的觀點,這是響應請求的後臺服務,除了發送該數據具有相同的唯一標識。

上述方案將能在你們來篩選由後臺服務通過按次事件聚合公佈的事件。

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

通常我給EventMessage附加一個參數,它定義了哪個ViewModel應該處理事件。如果該值可以爲空(這意味着任何VM可以處理它),我經常一個Handled屬性添加到事件消息並處理該事件將eventParams.Handled = true

例如,將事件發佈到同一個虛擬機中的第一視圖模型,我會用語法如下:

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

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

爲了處理那些只有一個視圖模型來處理事件,代碼可能是這樣的:

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