Here is my Implementation of IDataErrorInfo, hoping you will find it usfull.
1- Add a class ValidatorBase to the project’s ValidatorClasses
public class ValidatorBase
{
public System.Collections.Hashtable errors = new Hashtable();
public string GetError(string columnName)
{
string val = errors[columnName] as string;
return (val != null) ? val : null;
}
public string GetError()
{
if (errors.Count > 0)
{
System.Text.StringBuilder errString = new System.Text.StringBuilder ();
foreach (string s in errors.Keys)
{
errString.Append (s);
errString.Append (", ");
}
errString.Append ("Have errors");
return errString.ToString ();
}
else
return "";
}
public void ClearError(string columnName)
{
errors.Remove(columnName);
}
public ValidatorBase(){}
}
2- Let Validator Classes Inherit from ValidatorBase.
3 - Let Each EntityClass (supposing the two-class scenario) implement the interface IDataErrorInfo
as in the following Example:
public class ItemEntity : ItemEntityBase, IDataErrorInfo
{
#region Included Code
//IDataErrorInfo Members
string IDataErrorInfo.this[string columnName]
{
get {return ((ValidatorBase)Validator).GetError(columnName);}
}
string IDataErrorInfo.Error
{
get{ return ((ValidatorBase)this.Validator ).GetError();}
}
public void ClearError(string FieldName)
{
((ItemValidator)this.Validator ).ClearError(FieldName);
}
#endregion
}
4- In GUI class add the following code
private void Control_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
if( ((Control)sender).DataBindings.Count!=0) _CurrentItem.ClearError(((Control)sender).DataBindings[0].BindingMemberInfo.BindingField );
}
private void Control_Validated(object sender, System.EventArgs e)
{
if( ((Control)sender).DataBindings.Count!=0)
{
this.errorProvider1.SetIconAlignment( (Control)sender,
ErrorIconAlignment.MiddleLeft);
this.errorProvider1.SetError(
(Control)sender, ((IDataErrorInfo)_CurrentItem)
[((Control)sender).DataBindings[0].BindingMemberInfo.BindingField ]);
if (errorProvider1.GetError((Control)sender)!="")
statusBar1.Text = ((IDataErrorInfo)_CurrentItem).Error;
else
statusBar1.Text="";
}
}
Here we suppose that:
_CurrentItem is an instance of ItemEntity
errorProvidor1 is an instance of ErrorProvider
statusBar1 is an instance of StatusBar
5- for all bound controls in the GUI classes attach Control_Validating to the Validating event handler and Control_Validated to the Vlaidated event handler
6- For each Entity Validator class write the desired code for the validate method as in the example:
public virtual bool Validate(int fieldIndex, object value)
{
bool validationResult = true;
switch ( (ItemFieldIndex) fieldIndex)
{
case ItemFieldIndex.Discount:
System.Int16 discount = (System.Int16) value;
validationResult= (discount <=100) && (discount >0);
if (!validationResult)
errors["Discount"] ="Disount must be between 0 and 100";
else
errors.Remove("Discount");
break;
default:
validationResult = true;
break;
}
return validationResult;
}