【问题标题】:Implementing validations in WPF PropertyGrid在 WPF PropertyGrid 中实现验证
【发布时间】:2010-12-09 08:24:47
【问题描述】:

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

会有一些常见的验证,如数值、必填字段等和一些与业务逻辑相关的验证(如值不能超过这个等)。

有哪些方法可以实现这一点(IDataErrorInfo 或其他)?

【问题讨论】:

    标签: .net wpf validation propertygrid idataerrorinfo


    【解决方案1】:

    如果您已经在 ViewModel 上实现了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>
    

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

    有关如何正确实现 IDataErrorInfo 的信息,请看这里:
    http://blogs.msdn.com/b/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
    尤其是查看“3.5 IDataErrorInfo Support”部分

    【讨论】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      我建议使用IDataErrorInfo。这样,验证逻辑将保持连接到 ViewModel 而不是 UIWPF 也有很好的支持。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-24
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-26
        相关资源
        最近更新 更多