2010-05-10 61 views
2

有時,視圖模型需要引發通知,視圖應該處理並做出響應,特別是,當這些不能被建模爲屬性和屬性更改通知時。View可以訂閱ViewModel CLR事件嗎?

MVVM Light中的任何內容都可以允許視圖偵聽事件並通過聲明式Xaml標記將視圖模型通知轉換爲用戶界面操作?

+0

你是什麼意思?虛擬機所應有的一切所需信息的視圖來表現自己,一個不應該需要虛擬機和視圖之間的通信通道。 – Timores 2010-05-10 22:56:27

+0

您是否在談論處理彈出窗口和導航? – vidalsasoon 2010-05-11 12:05:11

回答

2

在「純粹的」MVVM解決方案中,唯一應該將View連接到ViewModel的是Bindings。沒有什麼能夠阻止你將DataContext轉換爲ViewModel類型,並在視圖中掛鉤一個事件,但這種做法有悖於使用MVVM方法的目的。作爲替代方案,嘗試重新思考爲什麼你認爲你需要將事件提升到視圖:

  • 需要顯示彈出?隨着視圖模型將通知對象「插入」到綁定集合中,可以使用各種「彈出通知」的綁定列表以及適當的模板來在視圖上創建彈出窗口。
  • 需要強制打開一個下拉菜單,或者一些類似的UI操作?將用戶界面上的相應屬性綁定到視圖模型屬性,將模式設置爲雙向,並在視圖模型上進行適當設置。

等,等

1

你是正確的,有時需要視圖模型與視圖進行通信。一種方法是ViewModel引發View監聽的CLR事件。這可以在View的代碼隱藏中完成。

MVVM不是關於消除視圖的代碼隱藏!這是關於分離關注點並通過單元測試來提高可測試性的。

啓用ViewModel和View之間通信的另一種方法是引入一個接口(IView)。有關此方法的更多信息可在WPF Application Framework (WAF)項目網站上找到。

1

MVVMLight確實有一個支持的技術,用於處理從ViewModel向您的View發送消息。查看GalaSoft.MvvmLight.Messaging命名空間。有一種更好的方法可以發送dialod消息,然後是下面的示例,但這只是一個簡單的例子。

視圖模型

public MainPageViewModel() 
{ 
    Messenger.Default.Send("Payment"); 
} 

查看

public MainPage() 
{ 
    Messenger.Default.Register<string>(this, DialogRequested); 
} 

private DialogRequested(string message) 
{ 
    MessageBox.Show(message); 
} 
3

我個人認爲從提高虛擬機事件並在視圖在某些情況下可以接受趕上他們的技術。我通常更喜歡在這種場合下使用Messenger,尤其是如果您需要自定義事件參數(因爲聲明新事件參數類和新委託需要很多工作)。

而且,事件處理程序是視圖和視圖模型之間的緊密耦合,而你通常會喜歡一個鬆耦合的,但如果你是知道的事實和後果,那麼爲什麼不...

另一種技術(例如,用於導航,對話框等)是聲明不同,需要(例如IDialogService與AskConfirmation和ShowMessage方法)的方法的接口。然後有一個類實現該接口(可以是主窗口/自身的MainPage),並把它傳遞給視圖模型(例如在視圖的構造函數的InitializeComponent被稱爲後右)。在VM中,需要時調用這些方法。這具有很容易測試的優點(簡單地嘲笑IDialogService和檢查方法被調用)。

我通常Messenger和IDialogService之間移動取決於多種因素。我傾向於最近雖然有利於界面爲基礎的方法,因爲它是一個比較容易測試(但Messenger是相當可測試也因此因人而異)。

乾杯, Laurent