使用 MVVMLight 訊息通知
歡迎閱讀我的MVVMLight教程系列文章《關於 MVVMLight 設計模式系列》
在文章的其實我們就說了,MVVMLight的精華就是訊息通知機制,設計的非常不錯。這個東西在MVVMLight可以說是用的及其的頻繁,當 ViewModel請求View要有些改變的時候(比如彈個窗體)那麼你在ViewModel裡面編寫彈窗的程式碼?那也就違背了MVVM的設計模式 啦,MVVMLight的訊息通知可以實現互相呼叫程式碼而不耦合!
如何使用 MVVMLight 訊息通知
接著我們上一篇文章的專案,也說過我們這裡要修改專案中的不足之處,讓程式碼優雅起來。目前為止我們一共有兩個窗體(MainWindow
UserView
),一個ViewModel(UserViewModel
)。我們在使用MainWindow
彈出UserView
的時候是直接編寫的MainWindow
中的Button
的Click
事件。這樣使得MainWindow
掌握了業務邏輯,按理什麼時候合理的彈出UserView
應該是編寫ViewModel的人員來決定的。所以我們應該把這個彈出視窗的權利交給ViewModel。
或許至此你會想在ViewModel中編寫如下程式碼?
- UserView uv = new UserView();
- uv.Show()
但是這樣寫,對嗎?…要是View的編寫人員還沒有編寫出UserView
下面我們來看看MVVMLight中的解決辦法 – 訊息通知
ViewModel是掌握業務邏輯的類,所以我們這裡廣播一個訊息,主意!我這裡說的是廣播!並不是我要指定這個訊息傳送給誰。
我在 UserViewModel.cs 中使用瞭如下程式碼進行了訊息廣播。
- Messenger.Default.Send<object>(null, "ShowUserView");
這個訊息傳送了個廣播,廣播的令牌為"ShowUserView"
這裡廣播出去的引數是 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教程系列文章《關於 MVVMLight 設計模式系列》 MVVMLight相關的我會在該目錄中進行補充。
轉載請註明:王旭部落格 » 使用 MVVMLight 訊息通知
繼續瀏覽有關 c# Messenger MVVM MVVMLight 訊息通知 的文章 使用 MVVMLight 訊息通知