将WPF验证规则应用于自定义用户控件内的文本框

4
我有一个自定义控件,在其中包含一个文本框。我想应用一些自定义验证规则,其中包括传递的参数(例如,实现范围检查)。
我想将验证规则应用于顶级自定义控件,如下所示。我已尽力删除不必要的代码,以使我的示例更加通用,但如果我没有完全成功,请谅解。我对在论坛上发布代码的想法有些新奇。
<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的设置内容,但在这个示例中似乎有点多余。核心是Style errorInTextBox,因为它设置了当验证规则失败时我希望自定义控件内的文本框如何表现。目前我能想到的最好的方法是使用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为true时起作用。问题在于由于验证规则针对的是自定义控件而不是其中的文本框,所以文本框似乎无法知道HasError的实际值。我尝试使用Validation.ErrorTemplate来修改borderbrush属性等,但模板似乎无法像我上面使用的Style.Resource那样访问文本框的属性,因此它不能修改文本框周围的边框等内容。
是否有任何解决方法?或者我应该放弃封装的想法,在需要验证时直接从头开始定义文本框,这将使我可以访问文本框的属性,但会导致大量冗余的XAML,并且似乎比我想要的方式不太优雅。
感谢所有人的关注和建议。
敬礼, Vik
1个回答

0

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

如果您可以在控件上设置规则,则在其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>

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


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

  • 向控件添加一个类型为ValidationRule的依赖属性。
  • 从模板中获取文本框(在OnApplyTemplate重写中使用Template.FindName)。
  • 获取文本框Text属性的绑定(有点棘手,现在不记得语法了)。
  • 将上述属性中的验证规则添加到绑定中。

感谢您的见解和回复。我对将验证规则设置为控件没有特别的设计反对意见,但我不确定如何使绑定正常工作,因为我不想将任何真实数据绑定到控件的顶层。此外,我不确定自定义控件的控件模板如何命名文本框。难道我不必将文本框的所有特性从我的控件xaml文件移动到控件模板中才能使其正常工作吗?再次感谢。 - user1426194

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接