Search code examples
silverlightinotifydataerrorinfo

How to implement INotifyDataErrorInfo for Datarow


i have a datarow class that implements Dynamicobject and INotifyPropertyChanged and INotifyDataErrorInfo

Also have a property called 'GridData'(datarows) in this class that is bound to xaml for displaying in the grid

May i know how to implement public IEnumerable GetErrors(string propertyName)

correctly since 'GridData' property can have many property bags

Thanks


Solution

  • //This is your row... more or less.
    public class GridData : DynamicObject, INotifyDataErrorInfo
    {
       private Dictionary<string, object> _propertyValues = new Dictionary<string, object>();
    
       //this object holds your errors.
       private Dictionary<string, List<ValidationResult>> _errorsContainer = new Dictionary<string, List<ValidationResult>>();
    
       //when this fires it notifies the UI the errors of this object have changed.
       public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
    
       //This tells the UI there are errors.
       public bool HasErrors
       { 
          get { return this._errorsContainer.Count > 0; }
       }
    
       //this allows the UI to retrieve all errors for a given property
       public IEnumerable GetErrors(string propertyName)
       {
          return this._errorsContainer[propertyName];
       }
    
       //This sets the error for a given property and fires the errors changed event
       protected void SetError(string propertyName, IEnumerable<ValidationResult> errors)
       {
          List<ValidationResult> existingErrors;
    
          if(this._errorsContainer.TryGetValue(propertyName, out existingErrors) != true)
          {
             this._errorsContainer[propertyName] = errors.ToList();
          }
          else
          { 
             existingErrors.AddRange(errors);
          }
    
          this.RaiseErrorsChanged(propertyName);
       }
    
       //This clears the errors for a given property
       protected void ClearErrors(string propertyName)
       {
          this._errorsContainer.Remove(propertyName);
          this.RaiseErrorsChanged(propertyName);
       }
    
       //This raises the event that the errors of this object have changed.
       protected void RaiseErrorsChanged(string propertyName)
       {
          if(this.ErrorsChanged != null)
          {
             this.ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
          }
       }
    
       //inherited from dynamic object this returns the value for a given property.
       public override bool TryGetMember(GetMemberBinder binder, out object result)
       {
          //this gives you the name of the property.
          string name = binder.Name;
    
          return _propertyValues.TryGetValue(name, out result);
       }
    
       //inherited from dynamic object, this is called when a property is set.
       public override bool TrySetMember(SetMemberBinder binder, object value)
       {
          string propertyName = binder.Name;
    
          List<ValidationResult> validationErrors = new List<ValidationResult>();
    
          //store the value in the propertyValues regardless if it is erroneous.
          _propertyValues[propertyName] = value;
    
          //this is where you test the value of the property.
          if(value /* whatever condition you use to test it */)
          {
             //no errors so update the ui.
             this.ClearErrors(propertyName);
          }
          else
          { 
             //there was an error for this value.
             ValidationResult result = new ValidationResult("The value is wrong.");
    
             //add the error to the list of errors for this property
             validationErrors.Add(result);
    
             //update the error container telling it there are errors for this property.
             //fire the errors changed event, and update ui.
             this.SetError(propertyName, validationErrors);  
          }
    
          return true;
       }
    
    }