You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF用户控件如何复用内部TextBox的验证模板?

问题描述

我有一个包含TextBlock和TextBox的WPF用户控件,当通过INotifyDataErrorInfo验证底层数据时,整个控件会显示红色边框。我希望让内部TextBox显示错误状态,就像直接使用TextBox时的效果(我使用的是WPF Material Design)。

用户控件XAML代码如下:

<UserControl ....>
    <Grid Height="40" Width="380" Margin="0,1,0,1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="110"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding ElementName=LabelWithInputUC,Path=Label}" Grid.Column="0" Margin="0,4,0,0" VerticalAlignment="Bottom"/>

            <TextBox VerticalAlignment="Bottom"
                     Margin="10,0,30,0" Grid.Column="1"
                     x:Name="ContentTextBox"
                     MaxLength="{Binding ElementName=LabelWithInputUC,Path=MaxLength}"
                     IsReadOnly="{Binding ElementName=LabelWithInputUC,Path=IsReadOnly}"
                     Text="{Binding ElementName=LabelWithInputUC,Path=Text,UpdateSourceTrigger=PropertyChanged}"/>            

    </Grid>
</UserControl>

其中Label、MaxLength、IsReadOnly和Text是用户控件的依赖属性。使用该控件的窗口将Text属性绑定到ViewModel的属性,并通过INotifyDataErrorInfo进行验证。

当我尝试将TextBox设置为控件的ValidationAdornerSite后,不再显示任何验证错误。请问如何让用户控件使用内部TextBox的错误模板?

解决方案

要实现让内部TextBox显示验证错误状态,需要完成以下关键操作:

1. 禁用用户控件自身的错误模板

默认情况下,用户控件会在自身渲染验证错误边框,先关闭这个行为,让错误提示转移到内部TextBox上。在UserControl标签中添加Validation.ErrorTemplate="{x:Null}":

<UserControl ....
             Validation.ErrorTemplate="{x:Null}">
    <!-- 原有Grid内容 -->
</UserControl>

2. 将内部TextBox关联为用户控件的验证装饰器目标

通过Validation.ValidationAdornerSiteFor属性,将TextBox指定为承载用户控件验证错误的容器,这样用户控件的验证错误就会渲染到TextBox上,沿用Material Design的TextBox错误样式:

<TextBox VerticalAlignment="Bottom"
         Margin="10,0,30,0" Grid.Column="1"
         x:Name="ContentTextBox"
         MaxLength="{Binding ElementName=LabelWithInputUC,Path=MaxLength}"
         IsReadOnly="{Binding ElementName=LabelWithInputUC,Path=IsReadOnly}"
         Text="{Binding ElementName=LabelWithInputUC,Path=Text,UpdateSourceTrigger=PropertyChanged}"
         Validation.ValidationAdornerSiteFor="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>

3. 确保Text依赖属性启用验证

检查用户控件的Text依赖属性定义,必须启用ValidatesOnNotifyDataErrors和ValidatesOnDataErrors,确保验证信息能从ViewModel传递到用户控件:

public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register(
        nameof(Text),
        typeof(string),
        typeof(LabelWithInputUC),
        new FrameworkPropertyMetadata(
            default(string),
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            null,
            null,
            false,
            UpdateSourceTrigger.PropertyChanged)
        {
            ValidatesOnNotifyDataErrors = true,
            ValidatesOnDataErrors = true
        });

public string Text
{
    get => (string)GetValue(TextProperty);
    set => SetValue(TextProperty, value);
}

完成以上修改后,当ViewModel通过INotifyDataErrorInfo返回验证错误时,错误状态会正确显示在内部TextBox上,呈现Material Design的默认错误样式,而不是整个用户控件显示红边框。

内容的提问来源于stack exchange,提问作者Marcel L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:12:59