【问题标题】:Applying wpf validation rules to a textbox inside a custom user control将 wpf 验证规则应用于自定义用户控件内的文本框
【发布时间】:2012-05-30 15:10:38
【问题描述】:

我有一个自定义控件,里面有一个文本框。我想应用一些包含传递参数的自定义验证规则(例如,实现范围检查)。

我想像这样将验证规则应用于顶级自定义控件。我已尽我所能修剪多余的代码以使我的示例更通用,但如果我还没有完全成功,请多多包涵。我对在论坛上发布代码的想法有些陌生。

<ns_control:CustomControl PropertyName="Value from embedded textBox:"  
    Style="{StaticResource errorInTextBox}">
        <ns_control:CustomControl.PropertyValue>
            <Binding Path="PathX"
                     Mode="TwoWay">
                                    <Binding.ValidationRules>
                                        <validation:IntegerInputRule Max="100" />
                                    </Binding.ValidationRules>
            </Binding>
        </ns_control:CustomControl.PropertyValue>
</ns_control:CustomControl>

好的,这就是控件的调用。我的实际代码中有一些东西,Validation.ErrorTemplate 也被设置为做某事,但这对这个例子来说似乎是多余的。样式 errorInTextBox 是问题的核心,因为它设置了我希望自定义控件中的 texbox 在验证规则失败时如何操作。到目前为止,我能够弄清楚如何做到这一点的最好方法是使用 Style.Resources 将我想要的样式应用于驻留在我的自定义控件中的任何文本框。

        <Style x:Key="errorInTextBox"
           TargetType="Control">
        <Style.Resources>
            <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}" />
                        <Setter Property="BorderBrush"
                                Value="Green" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Style.Resources>
    </Style>

如果发现错误,上面会显示工具提示并更改文本框的边框,或者至少这是我想要的。我的主要问题是 Style.Trigger——这是我的失败点。我希望当 Validation.HasError 为真时触发。问题是,由于验证规则是针对自定义控件而不是其中的文本框设置的,因此文本框似乎不知道 HasError 值实际上是什么。我尝试使用Validation.ErrorTemplate 来修改borderbrush 属性等,但模板似乎无法像我上面使用的Style.Resource 那样访问文本框的属性,因此它无法修改文本框周围的边框,等等。

有什么办法可以解决这个问题,还是我应该放弃封装的想法,而在我以这种方式使用自定义控件并且需要验证的任何地方直接从头开始定义文本框?在那里定义它们可以让我访问文本框属性,但它会导致大量多余的 XAML,并且看起来比我可以让它按照我想要的方式工作要优雅得多。

感谢大家的关注和建议。

问候, 维克

【问题讨论】:

    标签: wpf validation xaml


    【解决方案1】:

    从问题中我不确定您是否可以容忍在控件而不是文本框上设置验证规则。

    如果您可以在控件上设置规则,则在其ControlTemplate 中为文本框命名(我假设为x:Name="TextHolder")。在ControlTemplate.Triggers 添加:

    <Trigger Property="Validation.HasError"
             Value="True">
        <Setter TargetName="TextHolder"
                Property="ToolTip"
                Value="{Binding RelativeSource={RelativeSource Self},
                Path=(Validation.Errors)[0].ErrorContent}" />
        <Setter TargetName="TextHolder"
                Property="BorderBrush"
                Value="Green" />
    </Trigger>
    

    这将检查控件的验证,如果验证失败,setter 将访问文本框的属性。


    如果您必须在文本框上设置规则 -

    • ValidationRule 类型的依赖属性添加到控件。
    • 从模板中获取文本框(Template.FindName 来自 OnApplyTemplate 覆盖)。
    • 获取文本框Text属性的绑定(有点棘手,暂时不记得语法了)。
    • 将上述属性中的验证规则添加到绑定中。

    【讨论】:

    • 感谢您的洞察和回复。对于针对控件设置验证规则,我没有任何特定的设计反对意见,但我不确定如何使绑定正常工作,因为我没有想要绑定到控件顶层的真实数据。同样,我不确定自定义控件的控件模板如何用于命名文本框。我是否必须将控件内文本框的所有特征从我的控件 xaml 文件移动到控件模板中才能正常工作?再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2011-06-18
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多