如何为Datarow实现INotifyDataErrorInfo

时间:2015-01-08 04:55:01

标签: silverlight inotifydataerrorinfo

我有一个实现 Dynamicobject and INotifyPropertyChanged and INotifyDataErrorInfo

的datarow类

此类中还有一个名为 'GridData'(datarows) 的属性,该属性绑定到xaml以便在网格中显示

我可以知道如何实施 public IEnumerable GetErrors(string propertyName)

正确,因为 'GridData' 属性可以包含许多属性包

由于

1 个答案:

答案 0 :(得分:0)

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

}