使用 MVVMLight 消息通知

歡迎閱讀個人MVVMLight教程系列文章關於 MVVMLight 設計模式系列html

在文章的其實咱們就說了,MVVMLight的精華就是消息通知機制,設計的很是不錯。這個東西在MVVMLight能夠說是用的及其的頻繁,當 ViewModel請求View要有些改變的時候(好比彈個窗體)那麼你在ViewModel裏面編寫彈窗的代碼?那也就違背了MVVM的設計模式 啦,MVVMLight的消息通知能夠實現互相調用代碼而不耦合!c#

 

MVVMLight_Messenger

如何使用 MVVMLight 消息通知

接着咱們上一篇文章的項目,也說過咱們這裏要修改項目中的不足之處,讓代碼優雅起來。目前爲止咱們一共有兩個窗體(MainWindowUserView),一個ViewModel(UserViewModel)。咱們在使用MainWindow彈出UserView的時候是直接編寫的MainWindow中的ButtonClick事件。這樣使得MainWindow掌握了業務邏輯,按理何時合理的彈出UserView應該是編寫ViewModel的人員來決定的。因此咱們應該把這個彈出窗口的權利交給ViewModel。設計模式

或許至此你會想在ViewModel中編寫以下代碼?

  1. UserView uv = new UserView();
  2. uv.Show()

可是這樣寫,對嗎?…要是View的編寫人員尚未編寫出UserView這個類呢?是否是仍是沒有脫離耦合?仍是有這樣的依賴性,不是View依賴ViewModel,就是ViewModel依賴View,如何解決?mvvm

 

下面咱們來看看MVVMLight中的解決辦法 – 消息通知

ViewModel是掌握業務邏輯的類,因此咱們這裏廣播一個消息,主意!我這裏說的是廣播!並非我要指定這個消息發送給誰this

我在 UserViewModel.cs 中使用了以下代碼進行了消息廣播。spa

  1. Messenger.Default.Send<object>(null, "ShowUserView");

這個消息發送了個廣播,廣播的令牌爲"ShowUserView",這是個令牌! 跟一個暗語同樣,哈哈!只要對的上的就能夠收到這個消息,因此咱們跟接收者(也就是編寫View的工程師)進行約定。到時候接收消息就靠這個令牌了。設計

這裏廣播出去的參數是 Object 類型的,因爲我什麼參數都不須要傳遞因此我設定了 Send<T> 這個泛型爲 object ,參數值爲 null (也就是第一個參數)。code

 

接收MVVMLight的消息

約定好了一個令牌(這裏是「ShowUserView」),我在此註冊該令牌,有該令牌的消息時我會收到這個通知,看看咱們在View中是如何註冊消息並使用的吧!MainWindow.cs 的消息通知部分代碼以下!htm

  1. public MainWindow()
  2. {
  3.     this.DataContext = new MainWindowViewModel();
  4.     InitializeComponent();
  5.     
  6.     //註冊MVVMLight消息
  7.    Messenger.Default.Register<object>(this, "ShowUserView", ShowUserView);
  8.  
  9.     //卸載當前(this)對象註冊的全部MVVMLight消息
  10.     this.Unloaded += (sender, e) => Messenger.Default.Unregister(this);
  11. }
  12.  
  13. //彈出UserView窗體
  14. void ShowUserView(object obj)
  15. {
  16.     new UserView().Show();
  17. }

先看看註冊MVVMLight消息的那行代碼吧,Register<T> 這裏是一個泛型是和咱們約定好的同樣,我給了object類型,因此咱們構建的方法的時候也是要要有一個object類型的參數的方法ShowUserView(object obj)對象

ok,再繼續看看這行代碼後面的三個參數。

第一個:this  表示註冊該消息的對象,也就是消息接收人的意思,因此我填寫當前窗體。

第二個: "ShowUserView" 就是令牌了,跟ViewModel的編寫人員約定好的。

第三個:收到消息時要執行的方法,這裏咱們註冊的是  ShowUserView(object obj) 這個方法。

至此,完美! 誰也不依賴誰!何時彈出窗體,這些業務邏輯交給ViewModel的編寫人員吧。至於彈出什麼窗體,窗體多漂亮,窗體怎麼設置什麼的,這就是編寫View的事兒了。

 

彷佛還有個沒講…..卸載消息?

有註冊確定有註銷咯,若是你不註銷的話,這個註冊會一直存在。若是你打開了兩次MainWinodw則會註冊兩次。。兩個窗體都開着那麼收到一條消息的時候就會彈出4個UserView窗體..緣由很簡單就是由於註冊了兩次。。。每一個窗體就收到兩次。。

因此咱們在關閉窗體的時候或者你須要中止接收消息的時候來註銷消息接受。。。到這裏你應該明白 MVVMLight的消息註冊機制是一個靜態變量在App中全局廣播與註冊。帶來的麻煩確實有,可是有時候也異常的方便。不會存在多個窗體接力傳遞對象過去使用的狀況。

因此我這裏在Unloaded事件中對消息進行了註銷,下面看看註銷的代碼

  1. Messenger.Default.Unregister(this);

這個是註銷當前對象的全部消息,若是你想註銷指定的消息,那麼是有重載的,能夠指定令牌的名稱,如「ShwoUsreView」,敲敲代碼試試吧!以下所示!

  1. Messenger.Default.Unregister<object>(this, "ShowUserView");

 

 本文示例源碼下載MVVMLightDemo_4

 

至此MVVMLight的消息通知就差很少啦,有疑問或者其餘的建議…歡迎在此回覆進行討論!

歡迎閱讀個人MVVMLight教程系列文章關於 MVVMLight 設計模式系列》 MVVMLight相關的我會在該目錄中進行補充。

轉載請註明:王旭博客 » 使用 MVVMLight 消息通知

相關文章
相關標籤/搜索