我有一个数据对象用于包含支持INotifyPropertyChanged
和IDataErrorInfo
的UI数据。最初,我将所有的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>
今天我在重新组织程序时决定将各种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>
(我正在使用AdornerDecorator
,因为在以前的程序中,当切换标签页时错误样式没有重新渲染。我记不起来在哪里看到过这个,但它确实帮助了我。)
现在当我启动我的程序时,错误样式会正确地呈现在打开的TabItem
上,但不会正确地呈现在其他(隐藏的)TabItem
上。当我选择(并显示)其中的一个TabItem
时,错误样式的工具提示被设置,但错误图标图像没有显示。
我还测试了移除自定义样式并恢复默认的WPF文本框错误样式,我仍然得到类似的行为,即在程序打开时隐藏的TabItem
上没有控件周围的红色框。
因此,似乎我完全没有注意到什么东西阻止了错误样式在打开的标签项以外正确呈现。有任何想法吗?
编辑 Sep 3 修改说明以更好地理解我所看到的内容
谈论2014年的Déjà vu
现在是2014年11月,今天我遇到了这个愚蠢的WPF问题,错误模板不显示在标签控制器中呈现的项目上。脑海中的某些东西暗示我以前见过这个问题。所以我Google,第一件事就是我自己在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>
<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.Value> </Setter> </MultiTrigger> </Style.Triggers> </Style>
- dkl