CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo

今天晕晕糊糊的看CSLA.net,希望能找到验证数据正确性的方法,还是摸索出了INotifyPropertyChanged, IDataErrorInfo接口的使用方法,通过INotifyPropertyChanged实现了响应属性改变的事件,通过 IDataErrorInfo接口实现了在DataGridView或者GridControl中显示验证信息。

先看一个数据实体的抽象类:

 1  public abstract class BaseModel : INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo  2  {  3         protected BusinessRules mBusinessRules = new BusinessRules();  4 

 5         public event PropertyChangedEventHandler PropertyChanged;  6 

 7         public event PropertyChangingEventHandler PropertyChanging;  8 

 9         public BaseModel() 10  { 11             mBusinessRules.info = this; 12  AddRule(); 13  } 14 

15         public virtual void AddRule() 16  { 17             

18  } 19 

20         protected virtual void PropertyHasChanged(string name) 21  { 22             var propertyNames = mBusinessRules.CheckRules(name); 23 

24             foreach (var item in propertyNames) 25  OnPropertyChanged(item); 26  } 27 

28         protected virtual void OnPropertyChanged(string propertyName) 29  { 30             if (PropertyChanged != null) 31                 PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); 32 

33  } 34 

35         protected virtual void OnPropertyChanging(string propertyName) 36  { 37             if (PropertyChanging != null) 38                 PropertyChanging.Invoke(this, new PropertyChangingEventArgs(propertyName)); 39 

40  } 41 

42         #region IDataErrorInfo

43 

44         string IDataErrorInfo.Error 45  { 46             get

47  { 48                 return "Hello"; 49  } 50  } 51 

52         string IDataErrorInfo.this[string columnName] 53  { 54             get { return mBusinessRules.GetBrokenRules(columnName); } 55  } 56 

57         #endregion

58 

59     }
View Code

其中的BusinessRules对象mBusinessRules主要负责验证属性的正确性,这里只实现了一个粗糙版本的,没有抽象出验证规则Rule类。

将属性名和验证规则增加到mBusinessRules对象中,通过IDataErrorInfo的IDataErrorInfo.Error属性和IDataErrorInfo.this[string columnName]索引器验证每一列的正确性。Error是行头显示的提示信息。这里用到了lamda表达式和属性的遍历。

 1  public class BusinessRules  2  {  3         List<string> names = new List<string>();  4         List<string> exp = new List<string>();  5         public object info;//指向对象本身

 6 

 7         public List<string> CheckRules(string name)  8  {  9             return names; 10  } 11 

12         public string GetBrokenRules(string columnName) 13  { 14             for (int i = 0; i < names.Count; i++) 15  { 16                 List<object> list = new List<object>(); 17                 if (info == null) return null; 18                 Type t = info.GetType(); 19                 IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == columnName.ToLower() select pi; 20                 //IEnumerable<System.Reflection.PropertyInfo> property = t.GetProperties();

21                 foreach (PropertyInfo prpInfo in property) 22  { 23                     string sProName = prpInfo.Name; 24                     object obj = prpInfo.GetValue(info, null); 25                     if (!Regex.IsMatch(obj.ToString(), exp[i])) 26  { 27                         return "Error"; 28  } 29  } 30  } 31             return ""; 32  } 33 

34         public void AddRule(string ColName, string RegexExpress) 35  { 36  names.Add(ColName); 37  exp.Add(RegexExpress); 38  } 39     }
BusinessRules

接下来是数据实体Student,继承自BaseModel

 1  public class Student : BaseModel  2  {  3         public Student(string name)  4  {  5             mName = name;  6  }  7         private string mName;  8         public string Name  9  { 10             get

11  { 12                 return mName; 13  } 14             set

15  { 16                 if (mName != value) 17  { 18                     mName = value; 19                     PropertyHasChanged("Name"); 20  } 21  } 22  } 23         public override void AddRule() 24  { 25             mBusinessRules.AddRule("Name", @"^-?\d+$"); 26  } 27 

28     }
Student

最后是调用和效果:

1  private void button1_Click(object sender, EventArgs e) 2  { 3             BindingList<Student> list = new BindingList<Student>(); 4             Student a = new Student("张三"); 5  list.Add(a); 6             Student b = new Student("张三三"); 7  list.Add(b); 8             gridControl1.DataSource = list; 9         }

CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo     CSLA.Net学习(3)INotifyPropertyChanged和IDataErrorInfo

图1 初始化程序                                                                   图2修改第一行数据后,第一行错误提示消失

行头没有处理,所以一直有提示信息。

提供一个较完整的验证基类:

 1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.Reflection;  5 using System.Text.RegularExpressions;  6 

 7 namespace AppSurveryTools.Base  8 {  9     public abstract class EntityBase : IDataErrorInfo  10  {  11         protected BussinessRules mBussiness = null;  12 

 13         public EntityBase()  14  {  15             mBussiness = new BussinessRules(this);  16  AddRules();  17  }  18         public virtual void AddRules()  19  {  20  }  21         public string Error  22  {  23             get { return ""; }  24  }  25 

 26         public string this[string columnName]  27  {  28             get

 29  {  30                 string error = mBussiness.CheckRule(columnName);  31                 return error;  32  }  33  }  34  }  35     public class BussinessRules  36  {  37         Dictionary<string, Rule> rules = new Dictionary<string, Rule>();  38         Object mObj = null;  39         private readonly Type _type;  40         public BussinessRules(object obj)  41  {  42             mObj = obj;  43             _type = mObj.GetType();  44  }  45         public void AddRules(string property, Rule rule)  46  {  47             if (!rules.ContainsKey(property))  48  {  49  rules.Add(property, rule);  50  }  51  }  52         public string CheckRule(string columnName)  53  {  54             if (rules.ContainsKey(columnName))  55  {  56                 Rule rule = rules[columnName];  57                 PropertyInfo[] properties = _type.GetProperties(BindingFlags.Public | BindingFlags.Instance);  58                 foreach (PropertyInfo prpInfo in properties)  59  {  60                     if (prpInfo.Name == columnName)  61  {  62                         object obj = prpInfo.GetValue(mObj, null);  63                         if (obj==null)  64  {  65                             return "";  66  }  67                         if (rule.RuleType == RuleTypes.RegexExpression)  68  {  69                             if (!Regex.IsMatch(obj.ToString(), rule.RegexExpression))  70  {  71                                 return rule.ErrorText;  72  }  73  }  74                         else if (rule.RuleType == RuleTypes.StringRequire)  75  {  76                             if (string.IsNullOrEmpty(obj.ToString()))  77  {  78                                 return rule.ErrorText;  79  }  80  }  81 

 82 

 83  }  84  }  85  }  86             return "";  87  }  88         public void RemoveRule(string property)  89  {  90             if (rules.ContainsKey(property))  91  {  92  rules.Remove(property);  93  }  94  }  95  }  96     public enum RuleTypes  97  {  98         RegexExpression = 0,  99         Int32Require = 1, 100         DoubleRequire = 2, 101         DataRequire = 3, 102         StringRequire = 4

103  } 104     public class Rule 105  { 106         public RuleTypes RuleType { get; set; } 107         public string ErrorText { get; set; } 108         public string RegexExpression { get; set; } 109         /// <summary>

110         /// 验证规则 111         /// </summary>

112         /// <param name="typeRule">验证类型</param>

113         /// <param name="error">提示信息</param>

114         /// <param name="expression">表达式</param>

115         public Rule(RuleTypes typeRule, string error, string expression) 116  { 117             if (typeRule == RuleTypes.RegexExpression) 118  { 119                 if (!string.IsNullOrEmpty(expression)) 120  { 121                     RegexExpression = expression; 122  } 123  } 124             RuleType = typeRule; 125             ErrorText = error; 126  } 127 

128         public string CheckRule(string RegexExpression) 129  { 130             return ""; 131  } 132  } 133 }
View Code

 调用方法:

继承基类EntityBase,重载方法AddRules()

1 public override void AddRules() 2  { 3             string express = "^([-]?(\\d|[1-8]\\d)[°](\\d|[0-5]\\d)['](\\d|[0-5]\\d)(\\.\\d+)?[\"]?[NS]?$)"; 4             mBussiness.AddRules("WGS84B", new Rule(RuleTypes.RegexExpression, "请输入正确的纬度数据", express)); 5             string express2 = "^([-]?(\\d|[1-9]\\d|1[0-7]\\d)[°](\\d|[0-5]\\d)['](\\d|[0-5]\\d)(\\.\\d+)?[\"]?[EW]?$)"; 6             mBussiness.AddRules("WGS84L", new Rule(RuleTypes.RegexExpression, "请输入正确的经度数据", express2)); 7             base.AddRules(); 8         }

 补充:类似的介绍 http://blog.csdn.net/t673afa/article/details/6066278

你可能感兴趣的:(property)