五、從GitHub瀏覽Prism示例代碼的方式入門WPF下的Prism之MVVM中的EventAggregator


這一篇我們主要再看完示例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 ().Publish(Message);

整個就結束了。看到這里我們還不知道在干啥,好像是從傳入到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 ().Subscribe(MessageReceived),來訂閱接收其他地方Publish的MessageSentEvent消息,在MessageReceived()方法中獲取傳入的參數,並添加到Messages中。

這里就是接收其他地方發送來的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,繼續往后看

我創建了一個C#相關的交流群。用於分享學習資料和討論問題。歡迎有興趣的小伙伴:QQ群:542633085


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM