Search code examples
wpfbindingdata-annotationsvalidationrules

WPF Binding : Use DataAnnotations for ValidationRules


I have read a lot of Blog post on WPF Validation and on DataAnnotations. I was wondering if there is a clean way to use DataAnnotations as ValidationRules for my entity.

So instead of having this (Source) :

<Binding Path="Age" Source="{StaticResource ods}" ... >
  <Binding.ValidationRules>
    <c:AgeRangeRule Min="21" Max="130"/>
  </Binding.ValidationRules>
</Binding>

Where you must have your

public class AgeRangeRule : ValidationRule 
{...}

I want the WPF Binding to go see the Age property and look for DataAnnotation a bit like this:

[Range(1, 120)]
public int Age
{
  get { return _age; }
  set
  {
    _age = value;
    RaisePropertyChanged<...>(x => x.Age);
  }
}

Any ideas if this is possible ?


Solution

  • The closest approach I found is :

    // This loop into all DataAnnotations and return all errors strings
    protected string ValidateProperty(object value, string propertyName)
    {
      var info = this.GetType().GetProperty(propertyName);
      IEnumerable<string> errorInfos =
            (from va in info.GetCustomAttributes(true).OfType<ValidationAttribute>()
             where !va.IsValid(value)
             select va.FormatErrorMessage(string.Empty)).ToList();
    
    
      if (errorInfos.Count() > 0)
      {
        return errorInfos.FirstOrDefault<string>();
      }
      return null;
    

    Source

    public class PersonEntity : IDataErrorInfo
    {
    
        [StringLength(50, MinimumLength = 1, ErrorMessage = "Error Msg.")]
        public string Name
        {
          get { return _name; }
          set
          {
            _name = value;
            PropertyChanged("Name");
          }
        }
    
    public string this[string propertyName]
        {
          get
          {
            if (porpertyName == "Name")
            return ValidateProperty(this.Name, propertyName);
          }
        }
    }
    

    Source and Source

    That way, the DataAnnotation works fine, I got a minimum to do on the XAML ValidatesOnDataErrors="True" and it's a fine workaround of Aaron post with the DataAnnotation.