为 WPF 组合 DataAnnotations 和 IDataErrorInfo
我正在编写一个 WPF 应用程序,我想使用数据注释来指定 Required
字段、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 并简单地使用验证器,但该实现实际上并未编译,我也看不到它是如何工作的。有问题的方法是这样的:
/// <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;
}
问题是没有提供GetValue
。他可能正在谈论继承 DependencyObject
时出现的 GetValue
,但语法仍然不起作用(它期望您传递 DependencyProperty
作为参数),但我使用的是常规 CLR 属性,并在 setter 上调用 OnPropertyChanged("MyProperty")
。
有没有好的方法将验证连接到 IDataErrorInfo 接口?
I am writing a WPF application and I want to use Data Annotations to specify things like Required
Fields, Range
, etc.
My ViewModel classes use the regular INotifyPropertyChanged
interface and I can validate the entire object easily enough using the C# 4 Validator
, but I would also like the fields to highlight red if they do not validate properly. I found this blog post here (http://blogs.microsoft.co.il/blogs/tomershamam/archive/2010/10/28/wpf-data-validation-using-net-data-annotations-part-ii.aspx) that talks about how to write your base view model to implement IDataErrorInfo
and simply use the Validator, but the implementation doesn't actually compile nor can I see how it would work. The method in question is this:
/// <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;
}
The problem is GetValue
is not provided. He could be talking about the GetValue
that comes when you inherit DependencyObject
, but the syntax still doesn't work (it expects you to pass DependencyProperty
as a parameter) but I'm using regular CLR properties with OnPropertyChanged("MyProperty")
being invoked on the setter.
Is there a good way to connect the validation to the IDataErrorInfo
interface?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用上面的代码作为起点,我通过 IDataErrorInfo 完成了这项工作。
您的问题集中在当您只有属性名称时获取属性的值,反射可以在这里提供帮助。
Using your above code as a starting point I got this working through IDataErrorInfo.
Your problem centred around getting the value of the property when you only have the property name, reflection can help here.
我知道这篇文章很旧,但我最近在这篇文章的帮助下解决了这个问题,同时做了一些优化。我想分享我的 ViewModelBase 的 IDataErrorInfo 实现。它使用属性获取器的编译表达式来加速属性值的访问。当类型加载到内存中时,我还会在后台线程上触发表达式编译。希望它在第一次调用 OnValidate 之前完成编译,因为表达式编译可能有点慢。谢谢和欢呼。
I know this post is old, but I recently solved this problem with help from this post, while making some optimizations along the way. I'd like to share my ViewModelBase's implementation of IDataErrorInfo. It uses compiled expressions for the property getters which speeds the property value access. I also fire off the expression compilations on background thread when the type is loaded into memory. Hopefully, it finishes compilation before the first call to OnValidate since expression compilation can be a bit slow. Thanks and cheers.