UserControl 中经过验证的文本框

Posted

技术标签:

【中文标题】UserControl 中经过验证的文本框【英文标题】:Validated Textbox in a UserControl 【发布时间】:2012-10-28 17:49:46 【问题描述】:

我创建了一个 UserControl - 一个带标签的TextBox,它工作得很好,除了验证模板。当出现错误时,验证控制模板会显示出来,但它会填满包括标签在内的整个空间。我只希望它和TextBox 一样大。如何解决这个问题?

这是 xaml:

<UserControl x:Class="Infrastructure.CustomControls.LabelTextBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="LTB">

    <Grid HorizontalAlignment="Binding">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock x:Name="tbl" 
                   FontFamily="Binding" 
                   FontSize="Binding" 
                   Text="Binding ElementName=LTB, Path=LabelText" 
                   Height="Binding ElementName=LTB, Path=LabelHeight" 
                   Width="Binding ElementName=LTB, Path=LabelWidth" 
                   VerticalAlignment="Center"/>
        <TextBox x:Name="tbx" 
                 Grid.Column="1" 
                 FontFamily="Binding" 
                 FontSize="Binding" 
                 IsReadOnly="Binding ElementName=LTB, Path=IsReadOnly" 
                 MaxLength="Binding ElementName=LTB, Path=TextMaxLength" 
                 Text="Binding ElementName=LTB, Path=Text" 
                 Height="Binding ElementName=LTB, Path=TextHeight"
                 Width="Binding ElementName=LTB, Path=TextWidth" 
                 VerticalAlignment="Center">
            <Validation.ErrorTemplate>
                <ControlTemplate>
                    <DockPanel LastChildFill="True" 
                               ToolTip="Binding ElementName=aep, Path=AdornedElement.(Validation.Errors)[0].ErrorContent">
                        <TextBlock DockPanel.Dock="Right" 
                                   Foreground="Red" 
                                   FontSize="14pt" Text="*" 
                                   Margin="-15,0,0,0" 
                                   FontWeight="Bold"/>
                        <Border BorderBrush="Red" BorderThickness="1">
                            <AdornedElementPlaceholder Name="aep"/>
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Validation.ErrorTemplate>
        </TextBox>
    </Grid>
</UserControl>

【问题讨论】:

如果为 DockPanel 设置 Width="Binding ElementName=tbx, Path=ActualWidth" 会发生什么? 【参考方案1】:

发生这种情况的原因是您在视图中实现了IDataErrorInfo,而不是您的UserControl。这会导致整个用户控件出现默认 WPF 红色边框。

要显示您定义的错误模板,您需要在您的用户控件中实现IDataErrorInfo,并将ValidatesOnDataErrors=True 添加到您的绑定表达式中。

如果您希望将IDataErrorInfo 逻辑保留在您的视图中而不是您的 UserControl 中(这很合理),您需要为视图中的用户控件定义一个验证模板:

<Window>
    <local:UserControl>
        <Validation.ErrorTemplate>
            <ControlTemplate>
                ...
            </ControlTemplate>
        </Validation.ErrorTemplate>
    </local:UserControl>
</Window>

要让它只显示文本框的边框,您可以使用一个转换器来调整边框的宽度,该转换器将整个用户控件的宽度作为参数并返回文本框的宽度;可能是这样的:

<Border BorderBrush="Red" BorderThickness="1" Width="Binding ElementName=ph, Path=ActualWidth, Converter=StaticResource myConverter">
    <AdornedElementPlaceholder Name="ph" />
</Border>

【讨论】:

【参考方案2】:

感谢您的回复,它帮助我找出问题所在。为此,我认为它很有用。

我所做的是以编程方式查询 UserControl 验证以查找 TextBoxChangedEvent 中的错误,并为 TextBox 手动设置验证错误 (http://wpftutorial.net/ValidationErrorByCode.html)。

【讨论】:

以上是关于UserControl 中经过验证的文本框的主要内容,如果未能解决你的问题,请参考以下文章

使用日期选择器在文本框中进行验证

绑定ListBox中Usercontrol的DependencyProperty

UserControl:如何转换依赖属性并绑定到结果

如何从UserControl访问父级的DataContext

WPF 自定义控件并使用(例如带水印和字体图标的文本框)

WPF 文本框不会触发依赖属性设置器