Silverlight 4 MVVM開發方式(一) 小黑端
一開始接觸WPF和Silverlight就對MVVM的開發方式非常有興趣,
MVVM是Model - View - ViewModel的縮寫,Model就是資料,View就是介面,ViewModel負責控制介面與資料,
是利用DataBinding的機制所產生出的設計模式,因此只適用於Silverlight和WPF。
此開發方式的目的就是讓程式開發人員和畫面設計人員可以同時進行工作,不用互相等待,
這也是為什麼微軟除了VS之外又出了BLEND的原因。
我們就用一個簡單的例子來試試看!!
小黑想用Silverlight做一個簡單的通訊錄,
剛開啟專案時,必須手動加入Microsoft.Expression.Interactions參考,
因為小黑不會畫介面,所以他找了卡瑪幫他畫介面,
首先想想通訊錄要有哪些資料,通訊錄內容有Name, Age, Phone,
因此小黑作了以下的Model:
1: public class UserCard : INotifyPropertyChanged{
   2:  3: private string _Name;
4: private string _Phone;
5: private int _Age;
   6:  7: public string Name {
8: get { return _Name; }
   9:         set {10: _Name = value;
11: Update("Name");
  12:         }  13:     }  14:    15:  16: public string Phone {
17: get { return _Phone; }
  18:         set {19: _Phone = value;
20: Update("Phone");
  21:         }  22:     }  23:    24:  25: public int Age {
26: get { return _Age; }
  27:         set {28: _Age = value;
29: Update("Age");
  30:         }  31:     }  32:  33: private void Update(string name) {
34: if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
  35:     }  36:  37: #region INotifyPropertyChanged Members
  38:  39: public event PropertyChangedEventHandler PropertyChanged;
  40:  41: #endregion
  42: }Model實踐了INotifyPropertyChanged介面,這樣Binding後,若資料有改變才能通知出來。
接著小黑只想要有新增、修改、刪除這三個功能,這部分就寫在VM裡:
1: public class UserCardViewModel : INotifyPropertyChanged{
2: private ObservableCollection<UserCard> _UserCardList;
3: private UserCard _NewUserCard;
4: private ICommand _AddCommand;
5: private ICommand _RemoveCommand;
6: private ICommand _ModifyCommand;
   7:  8: public ObservableCollection<UserCard> UserCardList {
9: get { return _UserCardList; }
  10:         set {11: _UserCardList = value;
12: Update("UserCardList");
  13:         }  14:     }  15:    16:  17: public UserCard NewUserCard {
18: get { return _NewUserCard; }
  19:         set {20: _NewUserCard = value;
21: Update("NewUserCard");
  22:         }  23:     }  24:    25:  26: public ICommand AddCommand {
  27:         get {28: if (_AddCommand == null) _AddCommand = new ActionCommand(Add);
29: return _AddCommand;
  30:         }  31:     }  32:    33:  34: public ICommand RemoveCommand {
  35:         get {36: if (_RemoveCommand == null) _RemoveCommand = new ActionCommand(Remove);
37: return _RemoveCommand;
  38:         }  39:     }  40:  41: public UserCardViewModel() {
42: _UserCardList = new ObservableCollection<UserCard>();
43: _NewUserCard = new UserCard();
  44:     }  45:  46: private void Update(string name) {
47: if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
  48:     }  49:  50: private void Add() {
  51:    52:     }  53:  54: private void Remove(object obj) {
  55:    56:     }  57:  58: #region INotifyPropertyChanged Members
  59:  60: public event PropertyChangedEventHandler PropertyChanged;
  61:  62: #endregion
  63: }  64: }而Modify可以用DataBinding的TwoWay解決,所以不必多一個Modify的函式,
決定好功能後,小黑跟卡瑪說新增的資料會從NewUserCard取得,所以Add不用參數,但是Remove就要傳入要刪除的資料。
接著小黑就只要把功能,也就是空白的函式內容做好即可,不必花心思在介面!
最終小黑作出的Add和Remove如下:
1: private void Add() {
2: if (_NewUserCard != null) {
   3:         UserCardList.Add(_NewUserCard);   4:     }   5: }   6:  7: private void Remove(object obj) {
8: UserCard card = obj as UserCard;
9: if (card != null) {
  10:         UserCardList.Remove(card);  11:     }  12: }小黑也不必等介面做好,可以直接做單元測試,所以小黑就先去睡覺了!
