這一篇我們主要再看完示例12、13後,寫了個例子,用於再Modules下執行ApplicationCommands,使用IActiveAware執行當前View的Commands,或者ApplicationCommands下的Comands,主要是使用View和region解耦了他們之間的關係。
這一篇主要是看示例14,分析並學習EventAggregator。
從14示例繼續學習Prism下的MVVM思想
1、引用關係
專案包含4個工程ModuleA、ModuleB、UsingEventAggregator、UsingEventAggregator.Core。
1.1、ModuleA引用了Prism.Wpf和UsingEvnetAggregator.Core;
1.2、ModuleB引用了Prism.Wpf和UsingEvventAggregator.Core;
1.3、UsingEventAggregator.Core引用了Prism.Core包;
1.4、UsingEventAggregator主工程引用了Prosm.unity、ModuleA、ModuleB、UsingEventAggregator.Core;
我們從引用關係最小的開始分析
2、UsingEventAggregator.Core工程
Core工程引用了Prism.Core
只包含了一個MessageSentEvent.cs類
MessageSenEvent繼承自PubSubEvent,全部Core下只有這點程式碼。
我們先不管他是幹啥的,去看其他的工程。
3、ModuleA工程
ModuleA工程引用了Prism.Wpf和UsingEventAggregator.Core
3.1 我們先觀察ModuleAModule.cs
ModuleAModule繼承自Prism.Modularity.IModule,再OnInitialized()方法中,關聯了MessageView和顯示區域LeftRegion的顯示位置關係。
3.2觀察Views下的MessageView.xaml
新增了名稱空間prism,新增了prism:ViewModelLocator.AutoWireViewModel=true用於自動關聯ViewModel
再MessageView.xaml中,主要有1個顯示控制元件TextBox用於顯示Message,一個Button按鈕控制元件,用於執行SendMessageCommand命令的方法,cs檔案中無新增內容
3.3觀察ViewModels下的MessageViewModel.cs
在MessageViewModel檔案中,MessageViewModel繼承自BindableBase,新增了IEventAggregator事件聚合器的欄位_ea,通過建構函式傳入的IEventAggregator型別的物件賦初始值,
建立了Message屬性,用於 繫結到介面的TextBox用於顯示,
建立了DelegateCommand 命令SendMessageCommand,並在建構函式中初始化繫結了SendMessage()方法。
SendMessage()方法中,呼叫欄位_ea物件的GetEvent
整個就結束了。看到這裡我們還不知道在幹啥,好像是從傳入到ViewModel建構函式_ea物件獲取一個事件,然後Publish一個物件出去,這個物件的型別是在UsingEventAggregator.Core中定義的。
忘記12 13示例的內容先,繼續往下看。
4、ModuleB工程
ModuleB工程引用了Prism.Wpf、UsingEventAggregator.Core
4.1、先來觀察入口的ModuleBModule.cs
ModuleBModule繼承自Prism.Modularity.IModule,在OnInitialized()方法中關聯了MessageList和顯示區域RightRegion的顯示位置關係。
4.2、觀察Views下的MessageList.xaml
新增了名稱空間prism,
新增了自動關聯ViewModel的prism:ViewModelLocator.AutoWireViewModel=true屬性。
設定了用於顯示的列表控制元件,並繫結了ItemSource到VM下的Messages屬性上,比較奇怪這裡沒有配置區域RgihtRegion,但是他們是不相關的,所以先不管。可能在別的地方,Prism的優勢就在這裡,這裡就是顯示ViewModel下的Messages的內容到ListBox控制元件上, cs檔案中無額外程式碼。
4.3、觀察ViewModels下的MessageListViewModel.cs
MessageListViewModel繼承自BindableBase.
設定了欄位IEventAggregator型別的_ea,並在建構函式中初始化了ea;
設定了ObServableCollection型別的物件Messages,並在建構函式中初始化了Messages;
在建構函式中使用_ea物件.GetEvent
這裡就是接收其他地方傳送來的Publish的MessageSentEvent的訊息。然後新增到自己的ObservableCollection中用於等待View的顯示。
5、主工程UsingEventAggregator
UsingEventAggregator引用了Prism.unity、ModuleA、ModuleB、UsingEventAggregator.Core;
5.1、先看App.xaml
新增了名稱空間prism,
修改Application為prism:Prism:PrismApplication,
去掉了StartUri屬性
5.2、App.cs
修改App繼承自PrismApplication,
重寫了CreateShell()方法,並設定預設啟動窗體
重寫了ConfigureModuleCatalog()方法,並新增了ModuleAModule和ModuleBModule。
5.3Views下的MainWindow.xaml
新增了名稱空間prism,和設定了附加依賴項屬性prism:ViewModelLocator.AutoWireViewModel=true用於關聯ViewModel,
新增了2個ContentControl控制元件,並設定了prism:RegionManager.RegionName="LeftRegion" 和prism:RegionManager.RegionName="RightRegion" 用於等待檢視關聯。cs檔案中無額外程式碼
5.4ViewModels下的MainWindowViewModel.cs
MainWindowViewModel繼承自BindableBase
新增了屬性Title,用於顯示在View下的Title
6執行示例程式碼並分析
前面分析完了所有的程式碼,我們執行起來
發現左側是ModuleA下的MessageView,檢視,點選Button後,會把輸入的內容顯示到右側的ModuleB下的MessageList中,
回憶一下
ModuleA在ModuleAModule的OnInitialized()方法關聯了MessageView檢視和LeftRegion顯示區域
ModuleB在ModuleBModule的OnInitialized()方法關聯了MessageList檢視和RightRion顯示區域
UsingEventAggregator.Core中建立了MessageSentEvent:PubSubEvent
在ModuleA專案的ViewModel的建構函式中,接收了IEventAggregator型別的ea物件,並在View中的Button點選時觸發的Command,使用這個物件ea到GetEvent.Publish方法傳送了出去一個字串。
在ModuleB專案的ViewModel的建構函式中,接收了IEventAggregator型別的ea物件,並在ViewModel的建構函式中使用ea物件的GetEvent.Subscribe()方法去訂閱了ModuleA中傳送的事件。整個過程就走完了。耦合性非常低。
這一篇就梳理完啦。這一篇和第13篇的IActiveAware配合使用效果更好,這篇比較簡單,先不寫Demo,繼續往後看