MVVM設計模式和在WPF中的實現(四) 事件繫結

小y發表於2017-06-12

系列目錄:

MVVM模式解析和在WPF中的實現(一)MVVM模式簡介

MVVM模式解析和在WPF中的實現(二)資料繫結

MVVM模式解析和在WPF中的實現(三)命令繫結

MVVM模式解析和在WPF中的實現(四)事件繫結

MVVM模式解析和在WPF中的實現(五)View和ViewModel的通訊 

MVVM模式解析和在WPF中的實現(六)用依賴注入的方式配置ViewModel並註冊訊息

0x00 為什麼要事件繫結

這個問題其實是很好理解的,因為事件是豐富多樣的,單純的命令繫結遠不能覆蓋所有的事件。例如Button的命令繫結能夠解決Click事件的需求,但Button的MouseEnter、窗體的Loaded等大量的事件要怎麼處理呢?這就用到了事件繫結。

0x01 事件繫結

要使用事件繫結需要藉助System.Windows. interactivity,如果安裝了Blend,裡面就包含了這個dll。需要在Interaction.Triggers裡面新增一個或多個EventTrigger並指定關注的的事件名稱,在EventTrigger中通過InvokeCommandAction來繫結事件對應的命令。圖中所示繫結了主視窗的Loaded事件,在事件觸發後會呼叫繫結的命令物件LoadedCommand的Execute方法執行命令,當命令繫結需要引數時可以通過繫結CommandParameter實現。需要指出的是之前在實現MyCommand的Execute方法時我們加入了CanExecute的判斷,因此事件觸發後是否能夠真正執行繫結的命令也受到繫結的LoadedCommand的CanExecute方法的影響。

 

0x02 帶EventArgs引數的事件繫結

上面介紹的事件繫結並不足以應對所有的情況,因為很多情況下我們還需要從事件的EventArgs中獲取資料,例如從MouseMove事件引數中獲取滑鼠位置和按鍵狀態等。但InvokeCommandAction在未對CommandParameter繫結的情況下給Execute方法傳遞的引數為null。因此我們需要自己寫一個類來處理事件到命令的繫結。

 

看一下上面我們用到的InvokeCommandAction,繼承自TriggerAction<DependencyObject>,TriggerAction是一個抽象類,我們只要繼承這個類並實現Invoke方法即可。TriggerAction在MSDN中的介紹如下:

https://msdn.microsoft.com/zh-cn/library/system.windows.interactivity.triggeraction(v=expression.40).aspx

我簡單實現了以下,程式碼如下圖所示,其中依賴項屬性是藉助propdp程式碼段生成的,要不實在記不住,輸入那麼多程式碼也好麻煩。使用的時候用來代替之前的InvokeCommandAction,不繫結CommandParameter則傳遞的就是事件的引數。如果繫結了CommandParameter,那麼傳遞的就是繫結的引數。

0x03 事件繫結的示例

有了MyEventCommand我們就可以繫結事件並獲取事件引數了。例項中繫結了窗體的Loaded事件和MouseMove事件,其中在MouseMove事件中我們使用自己的MyEventCommand物件接收事件物件,並顯示出滑鼠相對於窗體的位置以及各個按鍵的狀態。

 示例程式執行後如下所示

0x04 相關下載

https://github.com/durow/TestArea/tree/master/MVVMTest/EventBindingTest

相關文章