在上一篇写了Model的INotifyPropertyChanged接口实现,在Prism中有一个NotificationObject自动实现了这个接口,位于Microsoft.Practices.Prism.ViewModel命名空间下。也就是说,Prism推荐ViewModel继承这个NotificationObject类来自动实现INotifyPropertyChanged接口。看看NotificationObject都有啥:
1 public abstract class
NotificationObject : INotifyPropertyChanged 2
{ 3 protected
NotificationObject(); 4
5 protected void RaisePropertyChanged<T>(Expression<Func<T>>
propertyExpression); 6 protected void RaisePropertyChanged(params string
[] propertyNames); 7 protected virtual void RaisePropertyChanged(string
propertyName); 8 }
提供了几个很方面的接口,调用更方便了,例如:
1 public string
ModelName 2
{ 3 get { return
_ModelName; } 4 set
5
{ 6 _ModelName =
value; 7
8 RaisePropertyChanged("ModelName"
); 9
10
} 11 }
第二个RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression);是一个表达式,编译为一个Func委托,返回一个T类型。
例如可以这样用:
1 this.RaisePropertyChanged(() => this.MyDataSummary);
ViewModel的INotifyPropertyChanged接口和Model的INotifyPropertyChanged接口
ViewModel和Model它们二者都实现INotifyPropertyChanged接口并不矛盾。用途不一样。例如一个ViewModel可以包含多个其它的ViewModel,而它们有一个整体的HasChanged属性来标识是否有改变。这个时候这个整体的ViewModel的HasChanged属性就可以用整体的INotifyPropertyChanged,而局部的INotifyPropertyChanged实现了这个整体的INotifyPropertyChanged。看个例子:
1 using
Microsoft.Practices.Prism.ViewModel; 2
3 public class
MyViewModel3: NotificationObject 4
{ 5 public MyModel MyModelData { get; set
; } 6 public MyModel2 MyModelData2 { get; set
; } 7
8 public bool HasChanges { get; set
; } 9 public bool CanSave { get; set
; } 10
11 public
MyViewModel3(MyModel model, MyModel2 model2) 12
{ 13 MyModelData =
model; 14 MyModelData2 =
model2; 15
16 model.PropertyChanged += this
.OnPropertyChanged; 17
} 18
19 private void OnPropertyChanged(object
sender, PropertyChangedEventArgs args) 20
{ 21 if (args.PropertyName == "Name"
) 22
{ 23 this.HasChanges = true
; 24 this.RaisePropertyChanged(() => this
.CanSave); 25
} 26
} 27
} 28
29 public class
MyModel2 : INotifyPropertyChanged 30
{ 31 public event
PropertyChangedEventHandler PropertyChanged; 32
33 public int ModelID { get; set
; } 34
35 private string
_ModelName; 36 public string
ModelName 37
{ 38 get { return
_ModelName; } 39 set
40
{ 41 _ModelName =
value; 42
43 if (PropertyChanged != null
) 44
{ 45 PropertyChanged(this, new PropertyChangedEventArgs("ModelName"
)); 46
} 47
} 48
} 49
} 50
51 public class
MyModel : INotifyPropertyChanged 52
{ 53 public event
PropertyChangedEventHandler PropertyChanged; 54
55 public int ModelID { get; set
; } 56
57 private string
_ModelName; 58 public string
ModelName 59
{ 60 get { return
_ModelName; } 61 set
62
{ 63 _ModelName =
value; 64
65 if (PropertyChanged != null
) 66
{ 67 PropertyChanged(this, new PropertyChangedEventArgs("ModelName"
)); 68
} 69
} 70
} 71 }
此外,Validation既可以放在Model里面也可以放在ViewModel里面,看你的规则是否简单,是否涉及业务逻辑,有的复杂的业务逻辑validation的需要调用后台service的建议放到ViewModel中去做。