MVVM模式和在WPF中的實現(二)數據綁定

MVVM模式解析和在WPF中的實現(二)

數據綁定

系列目錄:html

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

MVVM模式解析和在WPF中的實現(二)數據綁定github

MVVM模式解析和在WPF中的實現(三)命令綁定ide

MVVM模式解析和在WPF中的實現(四)事件綁定佈局

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

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

0x00 數據綁定要達到的效果

數據綁定要達到什麼效果呢,就是在界面中綁定了數據源以後,數據在界面上的修改能反映到綁定源,同時綁定源的修改也能反映到界面上。從界面反映到綁定的數據源是很容易理解的,由於在綁定過程當中咱們指定了DataContext和Binding的對象,很容易找到綁定的源並修改。但數據源修改時怎麼通知界面呢?由於ViewModel中被綁定的屬性並不知道誰綁定了它,若是在ViewModel中存一個View的引用,在數據發生變化時修改View,這無疑又將ViewModel和View耦合在了一塊兒,並且這樣作View中相應的控件沒有開發完善難以進行測試,一樣View中控件類型或名稱發生改變時,ViewModel中相關代碼都須要修改。在WPF中從數據源通知界面發生變化是經過發送通知的方式進行的,你能夠想象一個string類型的Property,名字是TestString,在它發生變化時對着View大喊「TestString發生變化了,大家誰綁定了TestString須要跟着變啊!」,至於綁定的是TextBlock的Text,仍是Label的Content,仍是TextBox的Text,ViewModel並不關心,一樣喊了後結果如何ViewModel也不關心。View在收到這個通知後看有沒有綁定 了TestString的地方,找到了就修改,找不到就無論了,也不會在意這個通知是哪一個類型的ViewModel發的。這樣ViewModel和View就解耦了,誰也不依賴對方。spa

0x01 INotifyPropertyChanged接口

在WPF中可以實現ViewModel向View喊話功能的就是INotifyPropertyChanged接口,它就像一個大喇叭同樣,咱們實現了這個接口,就能夠經過觸發PropertyChanged事件並給出改變的數據源的對象和屬性名稱,以此來通知數據的變化。這個接口的實現是很是簡單的,下圖代碼就是一種很是簡易的實現方式。因爲在MVVM中全部的ViewModel和部分Model都須要實現這個接口來達到綁定的效果,所以通常會專門用一個類來實現這個接口,並將這個類做爲ViewModel等須要數據更改後發送通知的類的基類。code

 

0x02 ObservableCollection<T>集合

NotifyObject貌似把一切都解決了,可是考慮這樣一種狀況,有一個List<string>列表顯示人員名單,View中的一個ListBox綁定了這個列表。每次咱們添加新成員時,爲了能在View中當即看到結果必須調用RaisePropertyChanged方法讓ListBox控件從新加載數據源。這種作法執行了大量的無效操做,就像咱們只是改變了屏幕上一小部份內容卻要刷新整個屏幕以更新顯示同樣。若是添加的不是人員而是一種添加動做頻繁發生的操做,這種無效操做會極大影響性能。所以WPF提供了一個ObservableCollection<T>集合,能夠將數據項的添加、刪除等反映到View中綁定的控件上而無需咱們作任何操做。因此在遇到對集合添加、刪除等操做又須要使用數據綁定時要優先考慮ObservalbeCollection<T>。htm

0x03 數據綁定的示例

有了NotifyObject這個基類後,咱們就能夠測試數據綁定了。爲了讓示例針對性更強,該示例僅僅用到了數據綁定,未添加命令綁定等其它內容。示例界面如圖所示:

1. 拖動滑塊時,最上面TextBox中的數值會跟着變化,顯示滑塊條的當前值,同時主界面背景色的透明度也會跟着變化。

2. 左下角的DataGrid和右下角的ListBox以及右邊標籤爲下拉菜單的ComboBox中的數據都是同樣的。選中這三個控件中的某行時,其它兩個控件也會選中該項。右上方紫色方框內會顯示選中行的信息。

3. 在左下角DataGrid控件、右下角ListBox控件、右上角紫色區域的某一處修改數據時,其它兩處的數據也會隨着修改。

下面說明如何經過數據綁定實現上面的功能。

先說一下主界面的ViewModel,其中有double型屬性DoubleValue,TestData型屬性SelectedData,List<TestData>型屬性TestDataList。這裏沒有使用ObservableCollection集合由於不涉及到集合內數據項的動態添加和刪除。若是要使用ObservableCollection也很是簡單,只須要把List<TestData>改成ObservableCollection<TestData>便可。

功能1:Slider的Value、TextBox的Text和DockPanel的Background的Opacity都綁定了ViewModel中的DoubleValue。當拖動滑塊時,Slider的Value發生了變化,會更新ViewModel中的DoubleValue,DoubleValue更新後會調用RaisePropertyChanged方法觸發INotifyPropertyChanged中的PropertyChanged事件,並在事件參數中保存了發生改變的屬性名稱「DoubleValue」,這樣View中綁定了DoubleValue的屬性就要更新數據,TextBox的Text屬性綁定了DoubleValue,因此TextBox更新了Text以顯示最新的Slider的Value。一樣主界面最頂層的佈局容器DockPanel的Background中的Opacity也綁定了DoubleValue,更改後的表現就是背景色透明度發生了變化。整個過程如圖中藍色箭頭所示。

功能2:DataGrid、ComboBox、ListBox的ItemsSource都綁定了ViewModel中的TestDataList,因此他們的列表項都是同樣的。在DataGrid中咱們顯示了TestData的全部屬性,ComboBox中咱們只顯示了StringValue屬性,在ListBox中則重寫了數據項模板,按照咱們想要的方式顯示TestData中的BoolValue、AddDateTime、和IntValue。同時這三個控件的SelectedItem也都綁定了ViewModel中的SelectedData,所以當其中一個的選中項發生改變時,其它兩個控件的選中項也會相應發生改變,原理參照功能1。此外右上角紫色區域的幾個TextBox和一個CheckBox分別綁定了SelectedData的不一樣屬性,所以當SelectedData發生改變時,紫色區域內各個控件的顯示內容也會發生改變。

功能3:由於TestData類也繼承自NotifyObject,並且幾個屬性在發生改變時也會調用RaisePropertyChanged方法發出通知,所以全部綁定了這些屬性的控件也會隨着更新數據。表現出來就是在任何地方修改了TestData中的屬性,全部綁定了這些屬性的控件都會更新。

固然了,還須要在主界面的後臺代碼中把DataContext設置爲ViewModel的一個實例。

DataContext = new MainWindowViewModel();

其實上面不少功能能夠不借助ViewModel來實現的。例如功能1中把TextBox的Text直接綁定到Slider的Value上,一樣功能二中ListBox的SelectedItem也可直接綁定到DataGrid的SelectedItem上,之因此使用ViewModel是爲了演示MVVM模式下的數據綁定。

0x04 相關下載

示例代碼:https://github.com/durow/TestArea/tree/master/MVVMTest

 


更多內容歡迎訪問個人博客:http://www.durow.vip

相關文章
相關標籤/搜索