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

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

  public abstract class BaseModel : INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
{
protected BusinessRules mBusinessRules = new BusinessRules(); public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangingEventHandler PropertyChanging; public BaseModel()
{
mBusinessRules.info = this;
AddRule();
} public virtual void AddRule()
{ } protected virtual void PropertyHasChanged(string name)
{
var propertyNames = mBusinessRules.CheckRules(name); foreach (var item in propertyNames)
OnPropertyChanged(item);
} protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected virtual void OnPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
PropertyChanging.Invoke(this, new PropertyChangingEventArgs(propertyName)); } #region IDataErrorInfo string IDataErrorInfo.Error
{
get
{
return "Hello";
}
} string IDataErrorInfo.this[string columnName]
{
get { return mBusinessRules.GetBrokenRules(columnName); }
} #endregion }

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

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

  public class BusinessRules
{
List<string> names = new List<string>();
List<string> exp = new List<string>();
public object info;//指向对象本身 public List<string> CheckRules(string name)
{
return names;
} public string GetBrokenRules(string columnName)
{
for (int i = ; i < names.Count; i++)
{
List<object> list = new List<object>();
if (info == null) return null;
Type t = info.GetType();
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == columnName.ToLower() select pi;
//IEnumerable<System.Reflection.PropertyInfo> property = t.GetProperties();
foreach (PropertyInfo prpInfo in property)
{
string sProName = prpInfo.Name;
object obj = prpInfo.GetValue(info, null);
if (!Regex.IsMatch(obj.ToString(), exp[i]))
{
return "Error";
}
}
}
return "";
} public void AddRule(string ColName, string RegexExpress)
{
names.Add(ColName);
exp.Add(RegexExpress);
}
}

BusinessRules

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

  public class Student : BaseModel
{
public Student(string name)
{
mName = name;
}
private string mName;
public string Name
{
get
{
return mName;
}
set
{
if (mName != value)
{
mName = value;
PropertyHasChanged("Name");
}
}
}
public override void AddRule()
{
mBusinessRules.AddRule("Name", @"^-?\d+$");
} }

Student

最后是调用和效果:

  private void button1_Click(object sender, EventArgs e)
{
BindingList<Student> list = new BindingList<Student>();
Student a = new Student("张三");
list.Add(a);
Student b = new Student("张三三");
list.Add(b);
gridControl1.DataSource = list;
}

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

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

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

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

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions; namespace AppSurveryTools.Base
{
public abstract class EntityBase : IDataErrorInfo
{
protected BussinessRules mBussiness = null; public EntityBase()
{
mBussiness = new BussinessRules(this);
AddRules();
}
public virtual void AddRules()
{
}
public string Error
{
get { return ""; }
} public string this[string columnName]
{
get
{
string error = mBussiness.CheckRule(columnName);
return error;
}
}
}
public class BussinessRules
{
Dictionary<string, Rule> rules = new Dictionary<string, Rule>();
Object mObj = null;
private readonly Type _type;
public BussinessRules(object obj)
{
mObj = obj;
_type = mObj.GetType();
}
public void AddRules(string property, Rule rule)
{
if (!rules.ContainsKey(property))
{
rules.Add(property, rule);
}
}
public string CheckRule(string columnName)
{
if (rules.ContainsKey(columnName))
{
Rule rule = rules[columnName];
PropertyInfo[] properties = _type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prpInfo in properties)
{
if (prpInfo.Name == columnName)
{
object obj = prpInfo.GetValue(mObj, null);
if (obj==null)
{
return "";
}
if (rule.RuleType == RuleTypes.RegexExpression)
{
if (!Regex.IsMatch(obj.ToString(), rule.RegexExpression))
{
return rule.ErrorText;
}
}
else if (rule.RuleType == RuleTypes.StringRequire)
{
if (string.IsNullOrEmpty(obj.ToString()))
{
return rule.ErrorText;
}
} }
}
}
return "";
}
public void RemoveRule(string property)
{
if (rules.ContainsKey(property))
{
rules.Remove(property);
}
}
}
public enum RuleTypes
{
RegexExpression = ,
Int32Require = ,
DoubleRequire = ,
DataRequire = ,
StringRequire =
}
public class Rule
{
public RuleTypes RuleType { get; set; }
public string ErrorText { get; set; }
public string RegexExpression { get; set; }
/// <summary>
/// 验证规则
/// </summary>
/// <param name="typeRule">验证类型</param>
/// <param name="error">提示信息</param>
/// <param name="expression">表达式</param>
public Rule(RuleTypes typeRule, string error, string expression)
{
if (typeRule == RuleTypes.RegexExpression)
{
if (!string.IsNullOrEmpty(expression))
{
RegexExpression = expression;
}
}
RuleType = typeRule;
ErrorText = error;
} public string CheckRule(string RegexExpression)
{
return "";
}
}
}

调用方法:

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

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

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

05-11 07:56