转自http://www.dotblogs.com.tw/help/archive/2010/07/27/16844.aspx
一开始接触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: }
小黑也不必等介面做好,可以直接做单元测试,所以小黑就先去睡觉了!