当Validation.HasError为True时显示元素的WPF触发器问题求助
问题:Validation触发器无法控制Label的Visibility状态
以下是我使用的XAML标记:
<GroupBox Margin="10" Padding="20" Header="Case 5 - Custom Error Object"> <GroupBox.DataContext> <local:ViewModel4/> </GroupBox.DataContext> <StackPanel> <Label Name="AdornerElement" Style="{StaticResource ResourceKey=AdornerElementStyle}"/> <TextBox Text="{Binding Path=UserName, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}" Margin="0 10" Validation.ValidationAdornerSite="{Binding ElementName=AdornerElement}"> </TextBox> </StackPanel> </GroupBox>
对应的样式代码:
<Style x:Key="AdornerElementStyle" TargetType="Label"> <Setter Property="Visibility" Value="Collapsed"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Label"> <StackPanel Orientation="Horizontal" Background="LightCoral"> <Image Source="/clipart.png" Width="24" Margin="10"/> <ItemsControl ItemsSource="{Binding ElementName=AdornerElement, Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)}" VerticalAlignment="Center"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=ErrorContent.ValidationMessage}" Style="{StaticResource CustomErrorTypeStyle}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> <ControlTemplate.Triggers> <DataTrigger Binding="{Binding ElementName=AdornerElement, Path=Validation.HasError}" Value="True"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
当前问题:除触发器外其他功能均正常——若初始将Visibility设为Visible,错误信息可正常显示;但使用上述样式时,Label始终处于Collapsed状态。
解决方法
问题出在触发器的绑定路径上:Label自身的Validation.HasError不会自动关联到TextBox的错误状态,需要绑定到TextBox的Validation.HasError,而Label作为ValidationAdornerSite,其ValidationAdornerSiteFor属性会指向对应的TextBox,因此可以通过该属性获取目标控件的错误状态。
修正后的样式代码如下:
<Style x:Key="AdornerElementStyle" TargetType="Label"> <Setter Property="Visibility" Value="Collapsed"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Label"> <StackPanel Orientation="Horizontal" Background="LightCoral"> <Image Source="/clipart.png" Width="24" Margin="10"/> <ItemsControl ItemsSource="{Binding ElementName=AdornerElement, Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)}" VerticalAlignment="Center"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=ErrorContent.ValidationMessage}" Style="{StaticResource CustomErrorTypeStyle}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> <ControlTemplate.Triggers> <!-- 修正:绑定到ValidationAdornerSiteFor指向的控件的HasError状态 --> <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Validation.ValidationAdornerSiteFor).Validation.HasError}" Value="True"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
修改说明
- 将触发器的绑定从
ElementName=AdornerElement, Path=Validation.HasError改为RelativeSource={RelativeSource TemplatedParent}, Path=(Validation.ValidationAdornerSiteFor).Validation.HasError - 通过
RelativeSource TemplatedParent获取当前Label控件,再通过(Validation.ValidationAdornerSiteFor)指向关联的TextBox,最终绑定到TextBox的Validation.HasError属性 - 这样当TextBox的验证状态变化时,触发器能正确感知并切换Label的Visibility
内容的提问来源于stack exchange,提问作者vso
相关产品推荐
相关产品推荐

