使控件可见时未应用验证 ErrorTemplate

Validation ErrorTemplate not applied when the control is made visible

我有一个带验证的控件和一个最初不可见的错误模板设置。当 属性 一个 ContentControl 绑定到切换到它时,该控件变得可见。但是,当控件可见时,错误模板仅在绑定 属性 更新后应用。有什么想法为什么会发生这种情况以及我能做些什么吗?

XAML 控制片段:

<TextBox Name="UserNameTextBox" Grid.Row="0" Grid.Column="1" Style="{StaticResource WinformsErrorTemplate}" Text="{Binding Path=UserName, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" IsEnabled="{Binding Path=CanEditCredentials}"/>

XAML 错误模板:

        <!-- This error template style emulates a Winforms validation error icon -->
        <Style x:Key="WinformsErrorTemplate" TargetType="Control">
            <Setter Property="Margin" Value="3"/>
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel LastChildFill="True">
                            <Ellipse DockPanel.Dock="Right" 
                                     ToolTip="{Binding ElementName=myTextbox, 
                                              Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
                                     Width="15" Height="15" 
                                     Margin="-25,0,0,10"
                                     StrokeThickness="1" Fill="Red" >
                                <Ellipse.Stroke>
                                    <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                                        <GradientStop Color="#FFFA0404" Offset="0"/>
                                        <GradientStop Color="#FFC9C7C7" Offset="1"/>
                                    </LinearGradientBrush>
                                </Ellipse.Stroke>
                                <Ellipse.Triggers>
                                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                        <BeginStoryboard Storyboard="{StaticResource FlashErrorIcon}"/>
                                    </EventTrigger>
                                </Ellipse.Triggers>
                            </Ellipse>
                            <TextBlock DockPanel.Dock="Right" 
                                       ToolTip="{Binding ElementName=myControl, 
                                                Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
                                       Foreground="White"
                                       FontSize="11pt" 
                                       Margin="-15,0,0,5" FontWeight="Bold">!
                                <TextBlock.Triggers>
                                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                        <BeginStoryboard Storyboard="{StaticResource FlashErrorIcon}"/>
                                    </EventTrigger>
                                </TextBlock.Triggers>
                            </TextBlock>
                            <Border BorderBrush="Red" BorderThickness="1" Margin="0,0,0,10">
                                <AdornedElementPlaceholder Name="myControl"/>
                            </Border>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip"
                            Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                                   Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

找到解决方案。问题是在 Window 级别有一个 AdornerDecorator,但在任何 UserControls 中都没有。因此,ErrorTemplate 无法呈现。解决方法是将 UserControl 下面的所有内容封装在 AdornerDecorator 中:

<UserControl>
    <AdornerDecorator>
        <StackPanel>
            ...
        </StackPanel>
    <AdornerDecorator>
</UserControl>

有关详细信息,请参阅 Validation ErrorTemplate not showing on data errors

我在一个选项卡控件内有多个视图的程序中遇到了同样的问题。 将显示验证错误,但当我切换到另一个选项卡并再次返回时会消失。 向每个视图添加 AdornerDecorator 解决了这个问题。 谢谢