原文: 使用 MVVMLight 消息通知 歡迎閱讀我的MVVMLight教程系列文章《 關于 MVVMLight 設計模式系列
》
在文章的其實我們就說了,MVVMLight的精華就是消息通知機制,設計的非常不錯。這個東西在MVVMLight可以說是用的及其的頻繁,當 ViewModel請求View要有些改變的時候(比如彈個窗體)那麼你在ViewModel裡面編寫彈窗的代碼?那也就違背了MVVM的設計模式 啦,MVVMLight的消息通知可以實作互相調用代碼而不耦合!
http://www.wxzzz.com/wp-content/uploads/2014/07/MVVMLight_Messenger.jpg如何使用 MVVMLight 消息通知
接着我們上一篇文章的項目,也說過我們這裡要修改項目中的不足之處,讓代碼優雅起來。目前為止我們一共有兩個窗體(
MainWindow
、
UserView
),一個ViewModel(
UserViewModel
)。我們在使用
MainWindow
彈出
UserView
的時候是直接編寫的
MainWindow
中的
Button
的
Click
事件。這樣使得
MainWindow
掌握了業務邏輯,按理什麼時候合理的彈出
UserView
應該是編寫ViewModel的人員來決定的。是以我們應該把這個彈出視窗的權利交給ViewModel。
或許至此你會想在ViewModel中編寫如下代碼?
- UserView uv = new UserView();
- uv.Show()
但是這樣寫,對嗎?…要是View的編寫人員還沒有編寫出
UserView
這個類呢?是不是還是沒有脫離耦合?還是有這樣的依賴性,不是View依賴ViewModel,就是ViewModel依賴View,如何解決?
下面我們來看看MVVMLight中的解決辦法 – 消息通知
ViewModel是掌握業務邏輯的類,是以我們這裡廣播一個消息,主意!我這裡說的是廣播!并不是我要指定這個消息發送給誰。
我在 UserViewModel.cs 中使用了如下代碼進行了消息廣播。
- Messenger.Default.Send<object>(null, "ShowUserView");
這個消息發送了個廣播,廣播的令牌為
"ShowUserView"
,這是個令牌! 跟一個暗語一樣,哈哈!隻要對的上的就可以收到這個消息,是以我們跟接收者(也就是編寫View的工程師)進行約定。到時候接收消息就靠這個令牌了。
這裡廣播出去的參數是 Object 類型的,由于我什麼參數都不需要傳遞是以我設定了 Send<T> 這個泛型為 object ,參數值為 null (也就是第一個參數)。
接收MVVMLight的消息
約定好了一個令牌(這裡是
“ShowUserView”
),我在此注冊該令牌,有該令牌的消息時我會收到這個通知,看看我們在View中是如何注冊消息并使用的吧!
MainWindow.cs
的消息通知部分代碼如下!
- public MainWindow()
- {
- this.DataContext = new MainWindowViewModel();
- InitializeComponent();
- //注冊MVVMLight消息
- Messenger.Default.Register<object>(this, "ShowUserView", ShowUserView);
- //解除安裝目前(this)對象注冊的所有MVVMLight消息
- this.Unloaded += (sender, e) => Messenger.Default.Unregister(this);
- }
- //彈出UserView窗體
- void ShowUserView(object obj)
- new UserView().Show();
先看看注冊MVVMLight消息的那行代碼吧,Register<T> 這裡是一個泛型是和我們約定好的一樣,我給了object類型,是以我們建構的方法的時候也是要要有一個object類型的參數的方法
ShowUserView(object obj)
。
ok,再繼續看看這行代碼後面的三個參數。
第一個:
this
表示注冊該消息的對象,也就是消息接收人的意思,是以我填寫目前窗體。
第二個:
"ShowUserView"
就是令牌了,跟ViewModel的編寫人員約定好的。
第三個:收到消息時要執行的方法,這裡我們注冊的是
ShowUserView(object obj)
這個方法。
至此,完美! 誰也不依賴誰!什麼時候彈出窗體,這些業務邏輯交給ViewModel的編寫人員吧。至于彈出什麼窗體,窗體多漂亮,窗體怎麼設定什麼的,這就是編寫View的事兒了。
似乎還有個沒講…..解除安裝消息?
有注冊肯定有登出咯,如果你不登出的話,這個注冊會一直存在。如果你打開了兩次MainWinodw則會注冊兩次。。兩個窗體都開着那麼收到一條消息的時候就會彈出4個UserView窗體..原因很簡單就是因為注冊了兩次。。。每個窗體就收到兩次。。
是以我們在關閉窗體的時候或者你需要停止接收消息的時候來登出消息接受。。。到這裡你應該明白 MVVMLight的消息注冊機制是一個靜态變量在App中全局廣播與注冊。帶來的麻煩确實有,但是有時候也異常的友善。不會存在多個窗體接力傳遞對象過去使用的情況。
是以我這裡在
Unloaded
事件中對消息進行了登出,下面看看登出的代碼
- Messenger.Default.Unregister(this);
這個是登出目前對象的所有消息,如果你想登出指定的消息,那麼是有重載的,可以指定令牌的名稱,如“ShwoUsreView”,敲敲代碼試試吧!如下所示!
- Messenger.Default.Unregister<object>(this, "ShowUserView");
本文示例源碼下載下傳:
MVVMLightDemo_4至此MVVMLight的消息通知就差不多啦,有疑問或者其他的建議…歡迎在此回複進行讨論!
》 MVVMLight相關的我會在該目錄中進行補充。
轉載請注明:
王旭部落格»
繼續浏覽有關
c# Messenger MVVM MVVMLight 消息通知的文章