WPF错误样式仅在选项卡控件的可见选项卡上正确呈现

Pet*_*r M 16 c# wpf tabs styles tabcontrol

我有一个数据对象用于包含支持INotifyPropertyChanged和我的UI数据IDataErrorInfo.最初我将所有UI控件都显示在一个大型WPF应用程序中,并且很高兴看到通过此自定义样式标记的错误:

    <!-- Set error style for textboxes -->
    <Style x:Key="txtBoxErrStyle" TargetType="{x:Type TextBox}">
        <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>

        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel DockPanel.Dock="Right">
                        <AdornedElementPlaceholder />
                        <Image Source="Error.png"
                                   Height="16"
                                   Width="16"
                                   ToolTip="{Binding Path=AdornedElement.ToolTip, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}" />
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
Run Code Online (Sandbox Code Playgroud)

我今天正在重新组织该程序,并决定将各种UI控件分发到几页TabControl.我正在使用的结构布局是:

<tabcontrol>
    <tabitem>
        <AdornerDecorator>
           [.. various Stack Panels, Groups and UI controls moved from original layout ..]
        </AdornerDecorator>
    </tabItem>
    <tabitem>
        <AdornerDecorator>
           [.. various Stack Panels, Groups and UI controls moved from original layout ..]
        </AdornerDecorator>
    </tabItem>

    ...
 </tabcontrol>
Run Code Online (Sandbox Code Playgroud)

(我正在使用AdornerDecorator我在之前的程序中遇到的错误样式,在交换标签页时不会重新呈现错误样式.我不记得我在哪里看到它但它确实帮助了我.)

现在,当我启动程序时,错误样式正确呈现在TabItem程序启动时打开,但在其他(隐藏)TabItems 上没有正确呈现.当我选择(并显示)其中一个时,TabItem设置错误样式的工具提示,但不显示错误图标图像.

我还测试了删除自定义样式并恢复为文本框的默认WPF错误样式,我仍然得到类似的行为,即TabItem在程序打开时隐藏的s 上的控件周围没有红框.

因此,似乎我完全遗漏了一些阻止错误样式从正确渲染除了打开选项卡Item之外的东西.有任何想法吗?

编辑9月3日 更改说明以支持更好地理解我所看到的内容

在2014年谈论Déjàvu

这是2014年11月和今天我有这个愚蠢的WPF问题,错误模板没有显示在选项卡控制器中显示的项目.我心中的一些东西表明我以前见过这个问题.所以我谷歌,弹出的第一件事是我自2009年以来的问题!

这次我看到dkl的评论,这是在我最后一次解决问题后添加的.所以我按照他的方式尝试并使用了这个解决方案(效果很好,我不需要在我的选项卡控件上使用Adorner控件):

<Style x:Key="TextBoxErrorStyle" TargetType="TextBox">
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="Validation.HasError" Value="True" />
                <Condition Property="IsVisible" Value="True" />
            </MultiTrigger.Conditions>
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel LastChildFill="True">
                            <TextBlock  DockPanel.Dock="Right" 
                                Foreground="Red"
                                FontSize="14pt" 
                                 Margin="-15,0,0,0" FontWeight="Bold">*
                            </TextBlock>
                            <Border BorderBrush="Red" BorderThickness="2">
                                <AdornedElementPlaceholder Name="controlWithError"/>
                            </Border>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="ToolTip" 
                    Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
        </MultiTrigger>
    </Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)

Ste*_*pel 20

(我正在使用AdornerDecorator,因为我在之前的程序中遇到过错误样式,在交换标签页时没有重新呈现.我不记得我在哪里看到这个,但它确实帮助了我)

据推测,这个确实重要的提示源自Karl Shifflets博客,至少他正在解决同一主题:切换TabItem时,TabControl内部的WPF验证错误消失.

鉴于此问题,您的问题可能只是相关的,即上面的提示/代码确保现在专用AdornerLayer于每个标签项,因为切换标签时将丢弃父元素的装饰层.这个专用的装饰层似乎仍然需要一些特殊处理,例如,请参阅问题WPF ErrorTemplate在未聚焦时可见?这基本上是颠倒你的问题.因此,我建议您根据自己的风格组合并扩展后者的概述解决方案,并尝试以下(尽管如此,未经测试的代码):

<Style x:Key="ErrorTemplate" TargetType="{x:Type TextBox}">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">...</Trigger>
        <Trigger Property="IsVisible" Value="false">
            <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
        </Trigger>
        <Trigger Property="IsVisible" Value="true">
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>...</Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)

请参阅我关于您更新单选按钮错误样式的评论,它试图类似地解决您可能相关的问题; 你真的在那里试过我的建议吗?

有关装饰体系结构的更多详细信息,请参阅" 装配体概述 ".

  • 你可以使用MultiTrigger简化:`<Style x:Key ="ErrorTemplate"TargetType ="{x:Type TextBox}"> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property ="Validation.HasError "Value ="True"/> <Condition Property ="IsVisible"Value ="True"/> </MultiTrigger.Conditions> <Setter Property ="Validation.ErrorTemplate"> <Setter.Value> ... </ Setter.值> </ Setter> </ MultiTrigger> </Style.Triggers> </ Style>` (3认同)

Aby*_*te0 5

Steffen Opel用他的链接解决了我的问题:切换TabItems时,TabControl内部的WPF验证错误消失了.

<TabControl>

  <TabItem>
    <AdornerDecorator>
      <StackPanel>
        ...
      </StackPanel>
    </AdornerDecorator>
  </TabItem>

  <TabItem>
    <AdornerDecorator>
      <StackPanel>
        ...
      </StackPanel>
    </AdornerDecorator>
  </TabItem>

  <TabItem>
    <AdornerDecorator>
      <StackPanel>
        ...
      </StackPanel>
    </AdornerDecorator>
  </TabItem>

</TabControl>
Run Code Online (Sandbox Code Playgroud)