Design Pattern
  • Introduction
  • Chapter1: MVVM
  • Chapter2: 觀察者模式 (Observer Pattern)
  • Chapter3: 策略模式 (Strategy Pattern)
  • Chapter4: 單例/獨體模式 (Singleton)
  • Chapter5: 裝飾者模式 (Decorater Pattern)
  • Chapter6: 命令模式 (Command Pattern)
  • Chapter7: MVC
Powered by GitBook
On this page
  • This section contain the following items:
  • 1.MVVM (Model-View-ViewModel)
  • 3.Two-Way Binding

Was this helpful?

Chapter1: MVVM

PreviousIntroductionNextChapter2: 觀察者模式 (Observer Pattern)

Last updated 5 years ago

Was this helpful?

This section contain the following items:

  • 1.MVVM (Model-View-ViewModel)

  • 2.MVVM Example: META (MOXA Engineer Test Application

  • 3.Two-Way Binding

1.MVVM (Model-View-ViewModel)

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放入

         xmlns:viewmodel="clr-namespace:WatchEample.ViewModel">
        <UserControl.Resources>
          <viewmodel:StopWatchViewModel x:Key="viewModel" x:Name="viewModel" />
        </UserControl.Resources>
        <Grid DataContext="{StaticResource ResourceKey=viewModel}">
      2.Page/Window:
        引用User Control, 以達到將視圖模組化的目的
        xmlns:view="clr-namespace:WatchEample.View">
        <view:BasicStopWatch Grid.Row="1" />

    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

        1. 與資料有關的功能,如產生資料則可放在Model

  • 架構

    • META涵蓋了四個部分: Test Reporter, Test Launcher, Test Editor, Test Scripts Tranfer

  • 4.操作 & 測試

    • 操作流程基本如下:

3.Two-Way Binding

1)何謂雙向綁定?

  • WPF透過原生的XAML檔和CodeBehind的cs, 提供了開發者分層的開發環境

    可將程式的運算邏輯與設計分層.一旦View的值被調整, 後方的資料也會被調整; 反之後方設定了值,

    View所顯示的內容也會更著改變,這稱為雙向綁定.

2)Example:

  • 建立一個View, 裡面有Listbox, 裡面放了一個TextBlock, 一個Textbox

    TextBlock及Textbox將連結到同一個資料, 因此若使用者修改Textbox中的數值,

    TextBlock的數值也將跟著改變

3)Cs:

  1. 新增一個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); } }

          #region INotifyPropertyChanged 成員
          public event PropertyChangedEventHandler PropertyChanged;
          #endregion
        }

    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:

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");

1)

2)

http://stackoverflow.com/questions/17967052/wpf-simple-binding-to-inotifypropertychanged-object
http://www.codeproject.com/Articles/41817/Implementing-INotifyPropertyChanged