2012-11-02 20 views
0

我仍然從MVVM開始閱讀所有的MSDN Prism示例,但我仍然喜歡一些指導,其中包含以下設計問題,我認爲這些問題將幫助我鎖定Prism概念並加強我剛剛瞭解如何解決MVVM範例中的以下設計? (newb)

我有一個多窗口應用程序 - 每個窗口都有一個濾鏡下拉控件。此過濾器控件的值將影響同一窗口中其他控件的顯示,例如網格,圖表等。

某些交互(例如,雙擊網格上的一行)將產生另一個窗口,該窗口將具有其自己的獨立過濾器控制,這將類似地影響只在該窗口內的其他控件的顯示

如何實現過濾器的這種行爲驅動其他用戶控件的顯示,它不知道和限制其行爲只有窗口託管它?我如何保持這些交互鬆散耦合?

我想我需要使用EventAggregator和篩選控件發佈更新事件時,選擇更改?我在想這個方法嗎?每個窗口都需要一個單獨的EventAggregator嗎?

回答

2

是的,你想這個正確的方式。 EventAggregator是你正在做的事情的好工具。您需要在每個計劃從中引發事件的窗口上都有EventAggregator。您可以將EA注入您的構造函數或使用ServiceLocator。以下是兩個示例:

// Ctor injection 
private IEventAggregator _eventAggregator; 
public ViewModelBase(IEventAggregator eventAggregator) 
{ 
_eventAggregator = eventAggregator; 
} 

// Service Locator 
ServiceLocator.Current.GetInstance<IEventAggregator>().GetEvent<YourEvent>().Publish(); 

現在,您需要爲EA創建一個CompositePresentationEvent來發布。您可以最大限度地減少通過在CPE中包含有效負載而創建的這些數量。事情是這樣的:

public class NavigationSelectedEvent : CompositePresentationEvent<NavigationEnum.Destination>{} 

所以,現在你已經準備好發佈事件:

_eventAggregator.GetEvent<NavigationSelectedEvent>().Publish(NavigationEnum.Destination.Home); 

然後訂閱它 - 有效載荷使用可選的過濾器,使你不浪費資源:

this.EventAggregator.GetEvent<NavigationSelectedEvent>().Subscribe(HandleNavigationEvent, ThreadOption.UIThread, false, i => i == NavigationEnum.Destination.Home); 
+0

好啊 - 這是我期待的有效載荷上的過濾器! 非常感謝您的指導,這實際上就是我心中的想法,很高興看到我處於正確的軌道上! :) – blue18hutthutt

+0

我有一個問題 - 我將如何設置當前ViewModel是MVVM導向方式的一部分?我有這樣的印象:虛擬機不知道綁定它們的視圖(以及窗口),因此如何告訴我的控件的虛擬機他們是哪個窗口的一部分? – blue18hutthutt

+0

@ blue18hutthutt ...你是對的,虛擬機不應該瞭解這些觀點。您需要在views/xaml中使用create Regions並使用RegionManager加載它們。 –

1

每個視圖都可以通過ViewModel訪問模型。建模您的過濾器。然後視圖綁定到使用過濾器的ViewModel表示形式。你的觀點不需要了解彼此,他們只需要綁定到模型。

2

您應該使用EventAggregator發佈過濾器通知,這是根據我的經驗做到的最好方法。您應該只使用一個EventAggregator作爲所有訂閱對象之間的樞紐。

喜歡的東西:

MyNotificationChangedArgs args = new MyNotificationChangedArgs(); 
args.Payload = GetThePayload(someParameters); 
myEventAggregator.GetEvent<NotificationFilterChangedEvent>().Publish(args); 

再就是通過Unity,真正幫助是依賴項注入EventAggregator,例如。這樣,所有控件都可以簡單地通過調用UnityContainer.Resolve方法訪問常用EventAggregator

var myEventAggregator = myUnityContainer.Resolve<MyEventAggregator>(); 
+0

我不需要爲每個新窗口單獨的EventAggregator?由於每個窗口都有一個單獨的過濾器控件實例,它只應用於該窗口中的控件,因此我不需要不同的EventAggregator,以免所有窗口的控件都註冊相同的過濾器?或者在事件有效載荷中包含窗口ID會更有意義? – blue18hutthutt

+0

@ blue18hutthutt:你應該只使用一個'EventAggregator',否則你會得到一個有趣的驚喜,LOL ... – code4life

+0

爲什麼會發生什麼? :) 那麼最好的做法是在事件的有效載荷中包含某種窗口ID? – blue18hutthutt