为WPF组合DataAnnotations和IDataErrorInfo

Nat*_*ugg 5 wpf idataerrorinfo data-annotations

我正在编写一个WPF应用程序,我想使用Data Annotations来指定诸如RequiredFields Range等的内容.

我的ViewModel类使用常规INotifyPropertyChanged接口,我可以使用C#4轻松地验证整个对象Validator,但如果它们没有正确验证,我还希望这些字段突出显示为红色.我在这里找到了这篇博文(http://blogs.microsoft.co.il/blogs/tomershamam/archive/2010/10/28/wpf-data-validation-using-net-data-annotations-part-ii.aspx )讨论如何编写基本视图模型来实现IDataErrorInfo并简单地使用Validator,但实现实际上并没有编译,也无法看到它是如何工作的.有问题的方法是这样的:

    /// <summary>
    /// Validates current instance properties using Data Annotations.
    /// </summary>
    /// <param name="propertyName">This instance property to validate.</param>
    /// <returns>Relevant error string on validation failure or <see cref="System.String.Empty"/> on validation success.</returns>
    protected virtual string OnValidate(string propertyName)
    {
        if (string.IsNullOrEmpty(propertyName))
        {
            throw new ArgumentException("Invalid property name", propertyName);
        }

        string error = string.Empty;
        var value = GetValue(propertyName);
        var results = new List<ValidationResult>(1);
        var result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = propertyName
            },
            results);

        if (!result)
        {
            var validationResult = results.First();
            error = validationResult.ErrorMessage;
        }

        return error;
    }
Run Code Online (Sandbox Code Playgroud)

GetValue没有提供问题.他可能正在谈论GetValue你继承的时候DependencyObject,但是语法仍然不起作用(它希望你DependencyProperty作为一个参数传递)但是我OnPropertyChanged("MyProperty")在setter上调用了常规的CLR属性.

有没有一种将验证连接到IDataErrorInfo界面的好方法?

ben*_*rce 5

使用上面的代码作为起点,我通过IDataErrorInfo完成了这项工作.

当你只有属性名时,你的问题集中在获取属性的值,反射可以在这里帮助.

public string this[string property]
{
   get
   {
      PropertyInfo propertyInfo = this.GetType().GetProperty(property);
      var results = new List<ValidationResult>();

      var result = Validator.TryValidateProperty(
                                propertyInfo.GetValue(this, null),
                                new ValidationContext(this, null, null)
                                {
                                  MemberName = property
                                }, 
                                results);

      if (!result)
      {
        var validationResult = results.First();
        return validationResult.ErrorMessage;
      }

      return string.Empty;
   }
}
Run Code Online (Sandbox Code Playgroud)