大家都知道微软在Asp.net Mvc中引入System.ComponentModel.DataAnnotations 命名空间,利用ValidationAttribute实现数据的校验,那么能不能把这种机制引入WinForm中呢?通过近两天的尝试发现,winform中很多组件都支持IDataErrorInfo接口实现的校验提示,我便想,如果让我们的这些校验特性的错误提示转到IDataErrorInfo接口实现中不久成功了吗?
下面就来尝试一下:
public abstract class EntityBase : INotifyPropertyChanged, IDataErrorInfo
{
private readonly Dictionary<string, PropertyInfo> _propertyGetters=new Dictionary<string, PropertyInfo>();
private readonly Dictionary<string, ValidationAttribute[]> _validators=new Dictionary<string, ValidationAttribute[]>();
private readonly Type _type;
protected EntityBase()
{
_type = GetType();
LoadData();
}
#region 私?有D方?法¨
private void LoadData()
{
PropertyInfo[] properties = _type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo propertyInfo in properties)
{
//拥μ有D的?验é证¤特?性?
object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(ValidationAttribute), true);
if (customAttributes.Length > 0)
{
_validators.Add(propertyInfo.Name, customAttributes as ValidationAttribute[]);
_propertyGetters.Add(propertyInfo.Name, propertyInfo);
}
}
}
///
/// 属?性?更ü改?通¨知a
///
///
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region IDataErrorInfo Members
///
/// 实μ现?IDataErrorInfo接ó口ú(获?取?校£验é未′通¨过y的?错í误ó提á示?)
///
public string Error
{
get
{
IEnumerable<string> errors = from d in _validators
from v in d.Value
where !v.IsValid(_propertyGetters[d.Key].GetValue(this,null))
select v.ErrorMessage;
return string.Join(Environment.NewLine, errors.ToArray());
}
}
///
/// 实μ现?IDataErrorInfo接ó口ú()
///
///
///
public string this[string columnName]
{
get
{
if (_propertyGetters.ContainsKey(columnName))
{
object value = _propertyGetters[columnName].GetValue(this,null);
string[] errors = _validators[columnName].Where(v => !v.IsValid(value))
.Select(v => v.ErrorMessage).ToArray();
OnPropertyChanged("Error");
return string.Join(Environment.NewLine, errors);
}
OnPropertyChanged("Error");
return string.Empty;
}
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
下面让我们的类继承该抽象类就可以了,下面是显示效果截图
短短的几十行代码,就实现了如此强大的功能,兴奋吧,当然要想让我们的框架实现更强大的验证功能,我们还可以实现自己的验证特性,这些在Asp.Net Mvc中已经司空见惯了,我就不多说了。