|
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Text;
namespace CodeProject.ComponentModel
{
[Serializable]
public class DataErrorInfo : IDataErrorInfo, INotifyPropertyChanged
{
private object target;
private HybridDictionary errors;
private int errorCount;
public DataErrorInfo(object target)
{
errors = new HybridDictionary();
this.target = target;
AddPropertyChangedListener(target as INotifyPropertyChanged);
}
public bool IsValid
{
get
{
return errorCount == 0;
}
}
public void Update()
{
Type type = target.GetType();
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
Update(propertyInfo);
}
}
public void Update(string propertyName)
{
Type type = target.GetType();
PropertyInfo propertyInfo = type.GetProperty(propertyName);
if (propertyInfo != null)
Update(propertyInfo);
}
public void Update(string propertyName, string error)
{
bool wasValid = IsValid;
if (!string.IsNullOrEmpty(this[propertyName]))
--errorCount;
errors[propertyName] = error;
if (!string.IsNullOrEmpty(error))
++errorCount;
if (wasValid != IsValid)
OnPropertyChanged("IsValid");
}
private void Update(PropertyInfo propertyInfo)
{
object[] attribs = propertyInfo.GetCustomAttributes(true);
if (attribs.Length == 0)
return;
string error = string.Empty;
object value = null;
foreach (object attrib in attribs)
{
ValidatorAttribute validator = attrib as ValidatorAttribute;
if (validator != null)
{
if (value == null)
{
value = propertyInfo.GetValue(target, null);
}
if (string.IsNullOrEmpty(validator.PropertyDescription))
validator.PropertyDescription = propertyInfo.Name;
error = validator.Validate(value);
if (!string.IsNullOrEmpty(error))
break;
}
}
Update(propertyInfo.Name, error);
}
private void AddPropertyChangedListener(INotifyPropertyChanged obj)
{
if (obj != null)
obj.PropertyChanged += target_PropertyChanged;
}
private void target_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Update(e.PropertyName);
}
#region IDataErrorInfo Members
public string Error
{
get
{
StringBuilder builder = new StringBuilder();
foreach (object error in errors.Values)
{
builder.AppendLine(error.ToString());
}
return builder.ToString();
}
}
public string this[string columnName]
{
get
{
if (errors.Contains(columnName))
return errors[columnName].ToString();
return string.Empty;
}
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Windows developer with 10+ years experience working in the banking industry.