Chapter1: MVVM
Last updated
Last updated
1.MVVM (Model-View-ViewModel)
2.MVVM Example: META (MOXA Engineer Test Application
3.Two-Way Binding
1.MVVM的優點是?
將與資料有關,及與UI有關的關注點分離
把"狀態"跟使用者"介面"分開
當對一個類別的改變需要牽動其他兩個類別, 而又會引起更多改變時, 這種現象稱為"shotgum surgery", 關注點分離可以防止這種問題的發生
code能被重複使用
例如我有很多個頁面, 但他們所binding的model並不全都100%相同, 如果有ViewModel
this.DataContext = this.plan_ChidWindow_NewTestPlan_ListBoxViewModel;
Model, View可被重新使用
2.MVC跟MVVM的差別是?
角色 (Role):
Model (模型)
用來表示與實作出應用程式內的各種資料物件,並且包含了商業處理邏輯。
View (檢視)
表示應用程式中的使用者介面(UI)所要顯示的各個元件。
Controller or ViewModel
MVC
以 Model-View-Controller 來表示
Controller: 實踐了策略模式
使用者接觸的對象用來處理使用者的互動與處理資料模型物件, 負責改變Model的狀態或是改變View的顯示
View:實踐了合成模式
將內容顯示給使用者,要顯示的內容則是由Model取得
Model:實踐了觀察者模式
當Model更新時,相關物件也會持續更新
MVVM
以 Model-View-ViewModel 來表示
View: 通常會需要使用到 XAML 標記宣告語言來定義,而 XAML 僅僅提供了使用者介面的宣告,並無法提供任何處理邏輯
ViewModel:扮演這存取資料模型的責任,並且透過了資料繫結技術將資料提供給檢視。
檢視僅知道檢視模型的存在,檢視模型僅知道模型的存在,而檢視模型並不知道檢視的存在,檢視也不知道模型的存在,因此充分做到的關注點分離的目的。
1) Model :
儲存/產生資料, 通常來自服務或是資料庫
宣告軟體的核心函式(自己需要使用到的函式/其他物件所要用到的函式), 至於使用這些函數的時機,也可以透過宣告或是import Model到ViewModel中再使用
Model記錄app目前的狀態,經常利用事件告訴app的其他部份狀態發生改變
2) View :
使用者直接與之互動的任何物件
View可分為以下兩種: 1.User Control: (1)製作Template: 訂出將來所會綁定的Property, 觸發事件(需宣告在code behind中) (2)加入資料來源: 一般來說會將專案中所有的ViewModel用StaticResource放入
3) ViewModel :
具有能夠被繫結到View裡頭之控制項的特性
User Control不可放進ViewModel
與Model溝通 (1)建立Model與View間的溝通介面:包裝/使用Model所Release的函式 (2)建立所有與視圖有關的Class: 例如converter (3)Model內先定義好OnEventTrigger, 並寫好發動OnEventTrigger的時機; ViewModel則定義EventHandler, 並向Model註冊
2.MVVM Example
1.需求
要能達到以下的需求:
1.可以做多台機器, 多種Model的測試
2.可以得到realtime的測試情形
3.使用者可以修改/編輯test plan
4.使用者可以擴充test case
5.測試完後可以自動產出test report
2.WireFrame
Stage 2 - META的開發, 開發流程如下:
以繪圖軟體描繪出外觀作為後續開發的基礎
3.Markdown & 設計軟體架構
檢視wireframe的設計,在wpf實作上的可行性, 並進行修改及優化
MVVM: 1. 視圖模組化, 切換頁面要重新組合時十分便利(策略模式) 2. 無論是單一Window或是User Control會連結到的model數量跟種類都不同, 但是ViewModel可以重複利用 3. 在User Control中再嵌入User Control (合成模式)
business logic要放在M, V,還是VM? 個人認為: 1. 與按鈕等與視圖有關的功能:
可放到View
如果還可能被利用到其他視圖中, 則可放到ViewModel
與資料有關的功能,如產生資料則可放在Model
架構
META涵蓋了四個部分: Test Reporter, Test Launcher, Test Editor, Test Scripts Tranfer
4.操作 & 測試
操作流程基本如下:
1)何謂雙向綁定?
WPF透過原生的XAML檔和CodeBehind的cs, 提供了開發者分層的開發環境
可將程式的運算邏輯與設計分層.一旦View的值被調整, 後方的資料也會被調整; 反之後方設定了值,
View所顯示的內容也會更著改變,這稱為雙向綁定.
2)Example:
建立一個View, 裡面有Listbox, 裡面放了一個TextBlock, 一個Textbox
TextBlock及Textbox將連結到同一個資料, 因此若使用者修改Textbox中的數值,
TextBlock的數值也將跟著改變
3)Cs:
新增一個class: public class testObj : INotifyPropertyChanged { private string test2 = null; public testObj() { test1 = "1"; test2 = "2"; } public string Test2 { set { test2 = value; OnPropertyChanged(new PropertyChangedEventArgs("Test2")); } get { return test2; } } protected void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) { PropertyChanged(this, e); } }
2.編輯MainWindows.cs: public partial class MainWindow : Window { public ObservableCollection moduleInfoList = new ObservableCollection(); public MainWindow() { InitializeComponent(); testObj module = new testObj(); this.moduleInfoList.Add(module); this.listBox.ItemsSource = this.moduleInfoList; } } 4)View (MainWindows.xaml):
目的是將TextBlock及Textbox連結到testObj中的Test2, 因此在tag中加入Mode=TwoWay:
</Grid.ColumnDefinitions> </Grid.RowDefinitions> </DataTemplate > </ListBox.ItemTemplate> </ListBox >
Reference:
1)http://stackoverflow.com/questions/17967052/wpf-simple-binding-to-inotifypropertychanged-object
2)http://www.codeproject.com/Articles/41817/Implementing-INotifyPropertyChanged
3.Model, View, ViewModel:
與View溝通 雙向綁定: ViewModel本身implement INotifyPropertyChanged: (1)宣告: public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler propertyChanged = PropertyChanged; if(propertyChanged != null){ propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } (2)觸發: 將會讓View中所綁定的欄位發生改變 OnPropertyChanged("LapSeconds");