.net 在WPF PropertyGrid中实现验证

.net 在WPF PropertyGrid中实现验证,.net,wpf,validation,propertygrid,idataerrorinfo,.net,Wpf,Validation,Propertygrid,Idataerrorinfo,我已经实现了一个PropertyGrid,其中显示了所选对象(在另一个库中)的属性。属性值通过绑定绑定到PropertyGrid控件。现在,我想对用户在PropertyGrid控件(主要是TextBox)中输入的值执行验证,并在值不正确时向用户显示消息 将有一些常见的验证,如数值、必填字段等,以及一些与业务逻辑相关的验证(如值不能超过此值等) 实现此功能的所有方法(IDataErrorInfo或其他方法)?我建议使用IDataErrorInfo。这样,验证逻辑将保持连接到ViewModel,而不

我已经实现了一个
PropertyGrid
,其中显示了所选对象(在另一个库中)的属性。属性值通过绑定绑定到
PropertyGrid
控件。现在,我想对用户在
PropertyGrid
控件(主要是
TextBox
)中输入的值执行验证,并在值不正确时向用户显示消息

将有一些常见的验证,如数值、必填字段等,以及一些与业务逻辑相关的验证(如值不能超过此值等)


实现此功能的所有方法(
IDataErrorInfo
或其他方法)?
我建议使用
IDataErrorInfo
。这样,验证逻辑将保持连接到
ViewModel
,而不是
UI
。而且
WPF
对它也有很好的支持。

如果您已经在ViewModels上实现了
IDataErrorInfo
,我发现此数据模板对于显示错误非常有用:

<Style TargetType="{x:Type TextBox}">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
        </Trigger>
    </Style.Triggers>
</Style>

这样,您只需在文本框绑定上设置
validatesOnDaerRors=True
,如果出现任何错误,就会得到一个显示错误的工具提示。这也可以应用于其他控件

有关如何正确实现IDataErrorInfo的信息,请查看此处:


特别是看一看“3.5 IDataErrorInfo支持”一节

我最近不得不处理这个问题,所以我将发布这个示例代码来帮助其他人解决同样的问题

using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace ValidationExample
{

    public class SomeClass : DataErrorInfoImpl
    {
        [CustomValidation(typeof (SomeClassValidator), "ValidateSomeTextToValidate")]
        string SomeTextToValidate {get;set;}

    }

    public class SomeClassValidator
    {
        public static ValidationResult ValidateNumberOfLevelDivisons(string text)
        {
            if (text != "What every condition i want") return new ValidationResult("Text did not meet my condition.");
            return ValidationResult.Success;
        }

    }

    public class DataErrorInfoImpl : IDataErrorInfo
    {
        string IDataErrorInfo.Error { get { return string.Empty; } }

        string IDataErrorInfo.this[string columnName]
        {
            get
            {
                var pi = GetType().GetProperty(columnName);
                var value = pi.GetValue(this, null);

                var context = new ValidationContext(this, null, null) { MemberName = columnName };
                var validationResults = new List<ValidationResult>();
                if (!Validator.TryValidateProperty(value, context, validationResults))
                {
                    var sb = new StringBuilder();
                    foreach (var vr in validationResults)
                    {
                        sb.AppendLine(vr.ErrorMessage);
                    }
                    return sb.ToString().Trim();
                }
                return null;
            }
        }
    }
}
使用System.Collections.Generic;
使用系统组件模型;
使用系统文本;
名称空间验证示例
{
公共类SomeClass:DataErrorInfoImpl
{
[CustomValidation(typeof(SomeClassValidator),“ValidateMetextToValidate”)]
字符串SomeTextToValidate{get;set;}
}
公共类验证程序
{
公共静态验证结果ValidateEnumberOfLevelDivisions(字符串文本)
{
if(text!=“What every condition Iwant”)返回新的ValidationResult(“text不符合我的条件”);
返回ValidationResult.Success;
}
}
公共类DataErrorInfoImpl:IDataErrorInfo
{
字符串IDataErrorInfo.Error{get{返回字符串.Empty;}}
字符串IDataErrorInfo。此[string columnName]
{
得到
{
var pi=GetType().GetProperty(columnName);
var value=pi.GetValue(这个,null);
var context=newvalidationcontext(this,null,null){MemberName=columnName};
var validationResults=新列表();
if(!Validator.TryValidateProperty(值、上下文、validationResults))
{
var sb=新的StringBuilder();
foreach(validationResults中的var vr)
{
sb.AppendLine(vr.ErrorMessage);
}
使某人恢复原状;
}
返回null;
}
}
}
}

此样式应适用于WPF Xceed.PropertyGrid和WPF PropertyTools.PropertyGrid。

谢谢Botz,请提供一些代码,说明如何在ViewModels中实现IDataErrorInfo。实际上,在我的例子中,我的控件(从UserControl派生)中有依赖属性,我需要验证这些属性。我添加了一个链接,您可以在其中看到如何实现它。我昨天看到了那篇文章,但我对如何用继承的控件实现IDataErrorInfo感到困惑。我有一个BaseControl(具有一些常见的依赖属性),我的控件继承自这个BaseControl,并具有一些其他依赖属性。我需要对所有依赖项属性(父项+子项)执行验证。我不太明白。通常在ViewModels(即控件绑定到的对象)上实现IDataErrorInfo。我认为不应该在控件本身上实施。您的控件甚至不知道要验证什么,只有您的数据对象知道。您可能是对的,但在我的场景中,我们不使用MVVM。有两个自定义控件库,一个具有控件,另一个具有PropertyGrid。现在,我的自定义控件具有各种依赖属性,PropertyGrid使用这些属性使它们可编辑。