Implementin IDataErrorInfo and using ErrorProvider

Posts   
 
    
prog
User
Posts: 1
Joined: 16-Nov-2005
# Posted on: 16-Nov-2005 18:20:20   

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;
    }


Otis avatar
Otis
LLBLGen Pro Team
Posts: 39896
Joined: 17-Aug-2003
# Posted on: 17-Nov-2005 10:17:52   

Good suggestion! smile Thanks! simple_smile

Frans Bouma | Lead developer LLBLGen Pro