CTZ*_*tef 5 validation wpf textbox tabcontrol adornerdecorator
我有一个非常类似于这些的问题:
具有验证的文本框在选项卡更改时丢失ErrorTemplate
AdornerDecorator这样的伎俩同一个实例内的Window,但是当Window被重载,我切换到TabItem包含TextBox错误时,ErrorTemplate 会显示不出来了。
<Window x:Class="Views.MyWindowView">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl HorizontalAlignment="Stretch"
Height="Auto"
VerticalAlignment="Top"
Width="Auto"
SelectionChanged="TabItemChanged"
Name="MyTabControl">
<!-- Below, AdornerDecorator are added for the following reason:
the Validation.Error cues are painted in the Adorner Layer.
When tabs are switched, that layer is discarded. -->
<!-- The view 1 tab.-->
<TabItem Header="{Resx tab1_Header}"
Name="Tbi1">
<AdornerDecorator>
<vw:MyView1 DataContext="{Binding}"/>
</AdornerDecorator>
</TabItem>
<!-- The view 2 tab.-->
<TabItem Header="{Resx tab2_Header}"
Name="Tbi2">
<AdornerDecorator>
<vw:MyView2 DataContext="{Binding}"/>
</AdornerDecorator>
</TabItem>
</TabControl>
Run Code Online (Sandbox Code Playgroud)
...
我尝试在后面的代码中重新触发验证TabControl SelectionChanged,但无效。
任何的想法?
拼凑拼图的各个部分
一个AdornerLayer表示用于呈现装饰器的表面。由于AdornerLayer通常服务于整个视图,而不仅仅是一个控件,一些容器默认实现它们。
一个装饰器是一个自定义FrameworkElement绑定到一个UIElement。装饰器在 中渲染AdornerLayer,这是一个始终位于装饰元素或装饰元素集合之上的渲染表面。
因此,在这种情况下,装饰器(红色矩形)绑定到TextBox,但呈现在TextBox.
装饰(例如,在验证错误的情况下)是通过调用静态方法GetAdornerLayer获取要装饰的AdornerLayer对象来完成的UIElement。
足够的理论
更改TabItems会丢弃AdornerLayer,导致不会绘制装饰器。2个修复:
\DRapp 提出的手动方式:
<XAML for MyView1>
<AdornerDecorator>
...
</AdornerDecorator>
</close XAML for MyView1>
Run Code Online (Sandbox Code Playgroud)
当然,如果有另一个容器在( 在可视化树中)和( 在 )AdornerLayer之间实现了,这不会有任何好处。因此,显式需要是包装.AdornerDecoratorTextBoxAdornerDecoratorTextBox
<XAML for MyView1>
<Grid>
...
<GroupBox>
<AdornerDecorator>
<Grid>
...
<TextBox ... />
</Grid>
</AdornerDecorator>
</GroupBox>
</Grid>
</close XAML for MyView1>
Run Code Online (Sandbox Code Playgroud)
\第二个解决方案(我更喜欢)在每次变得可见时重置ErrorTemplateTextBox。在这样做时,缺乏AdornerLayer会被发现和修复。
<UserControl.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsVisible" Value="true">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)