[Silverlight入门系列]Validation:INotifyPropertyChanged和INotifyDataErrorInfo放在Model实现
时间:2011-03-14 来源:Mainz
Validation大概分以下几种:
- 类型和长度:比如 \d{1,3} 最多三位,必须数字
- 范围:比如a-zA-Z, 大于100小于200等
- 商业逻辑:特殊的,比如检查数据库某name唯一(需调用后台Service),或者其他的Business Logic等。
Silverlight4中validation实现INotifyPropertyChanged和INotifyDataErrorInfo接口,既可以放在Model中,也可以放在ViewModel中。(不要两个都实现哦)。如果你的validation规则比较简单,例如上面的第一二种,那么放在Model中比较合适。但是如果你的validation规则比较复杂特殊,需要用Business Logic,调用异步调用后台Service等,则放在ViewModel中比较合适。
Silverlight4.0增加了INotifyDataErrorInfo接口:
1: namespace System.ComponentModel
2: {
3: public interface INotifyDataErrorInfo
4: {
5: bool HasErrors { get; }
6: event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
7: IEnumerable GetErrors(string propertyName);
8: }
9: }
还有INotifyPropertyChanged接口:
1: namespace System.ComponentModel
2: {
3: public interface INotifyPropertyChanged
4: {
5: event PropertyChangedEventHandler PropertyChanged;
6: }
7: }
来一个例子:
1: public abstract class MyXXX: INotifyPropertyChanged, INotifyDataErrorInfo
2: {
3: private ErrorsContainer<ValidationResult> errorsContainer;
4:
5: /// <summary>
6: /// Initializes a new instance of the <see cref="DomainObject"/> class.
7: /// </summary>
8: protected MyXXX ()
9: {
10: }
11:
12: /// <summary>
13: /// Event raised when a property value changes.
14: /// </summary>
15: /// <seealso cref="INotifyPropertyChanged"/>
16: public event PropertyChangedEventHandler PropertyChanged;
17:
18: /// <summary>
19: /// Event raised when the validation status changes.
20: /// </summary>
21: /// <seealso cref="INotifyDataErrorInfo"/>
22: public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
23:
24: /// <summary>
25: /// Gets the error status.
26: /// </summary>
27: /// <seealso cref="INotifyDataErrorInfo"/>
28: public bool HasErrors
29: {
30: get { return this.ErrorsContainer.HasErrors; }
31: }
32:
33: /// <summary>
34: /// Gets the container for errors in the properties of the domain object.
35: /// </summary>
36: protected ErrorsContainer<ValidationResult> ErrorsContainer
37: {
38: get
39: {
40: if (this.errorsContainer == null)
41: {
42: this.errorsContainer =
43: new ErrorsContainer<ValidationResult>(pn => this.RaiseErrorsChanged(pn));
44: }
45:
46: return this.errorsContainer;
47: }
48: }
49:
50: /// <summary>
51: /// Returns the errors for <paramref name="propertyName"/>.
52: /// </summary>
53: /// <param name="propertyName">The name of the property for which the errors are requested.</param>
54: /// <returns>An enumerable with the errors.</returns>
55: /// <seealso cref="INotifyDataErrorInfo"/>
56: public IEnumerable GetErrors(string propertyName)
57: {
58: return this.errorsContainer.GetErrors(propertyName);
59: }
60:
61: /// <summary>
62: /// Raises the <see cref="PropertyChanged"/> event.
63: /// </summary>
64: /// <param name="propertyName">The name of the changed property.</param>
65: [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Method supports event.")]
66: protected void RaisePropertyChanged(string propertyName)
67: {
68: this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
69: }
70:
71: /// <summary>
72: /// Raises the <see cref="PropertyChanged"/> event.
73: /// </summary>
74: /// <param name="e">The argument for the event.</param>
75: protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
76: {
77: var handler = this.PropertyChanged;
78: if (handler != null)
79: {
80: handler(this, e);
81: }
82: }
83:
84: /// <summary>
85: /// Validates <paramref name="value"/> as the value for the property named <paramref name="propertyName"/>.
86: /// </summary>
87: /// <param name="propertyName">The name of the property.</param>
88: /// <param name="value">The value for the property.</param>
89: protected void ValidateProperty(string propertyName, object value)
90: {
91: if (string.IsNullOrEmpty(propertyName))
92: {
93: throw new ArgumentNullException("propertyName");
94: }
95:
96: this.ValidateProperty(new ValidationContext(this, null, null) { MemberName = propertyName }, value);
97: }
98:
99: /// <summary>
100: /// Validates <paramref name="value"/> as the value for the property specified by
101: /// <paramref name="validationContext"/> using data annotations validation attributes.
102: /// </summary>
103: /// <param name="validationContext">The context for the validation.</param>
104: /// <param name="value">The value for the property.</param>
105: protected virtual void ValidateProperty(ValidationContext validationContext, object value)
106: {
107: if (validationContext == null)
108: {
109: throw new ArgumentNullException("validationContext");
110: }
111:
112: List<ValidationResult> validationResults = new List<ValidationResult>();
113: Validator.TryValidateProperty(value, validationContext, validationResults);
114:
115: this.ErrorsContainer.SetErrors(validationContext.MemberName, validationResults);
116: }
117:
118: /// <summary>
119: /// Raises the <see cref="ErrorsChanged"/> event.
120: /// </summary>
121: /// <param name="propertyName">The name of the property which changed its error status.</param>
122: [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Method supports event.")]
123: protected void RaiseErrorsChanged(string propertyName)
124: {
125: this.OnErrorsChanged(new DataErrorsChangedEventArgs(propertyName));
126: }
127:
128: /// <summary>
129: /// Raises the <see cref="ErrorsChanged"/> event.
130: /// </summary>
131: /// <param name="e">The argument for the event.</param>
132: protected virtual void OnErrorsChanged(DataErrorsChangedEventArgs e)
133: {
134: var handler = this.ErrorsChanged;
135: if (handler != null)
136: {
137: handler(this, e);
138: }
139: }
140: }
相关阅读 更多 +