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         }

     

图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

原文地址:https://www.cnblogs.com/yhlx125/p/3585467.html