我已经创建了自定义验证器和错误模板。错误模板如下。
<ControlTemplate x:Key="errorTmp">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Row="1" BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder x:Name="Adorner"/>
</Border>
<TextBlock Grid.Row="0" Foreground="Red" Text="{Binding ElementName=Adorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Margin="0,0,0,5"></TextBlock>
</Grid>
</ControlTemplate>
问题是错误消息在其他控件上重叠。
答案 0 :(得分:1)
您需要为装饰图层中的元素预留空间。您可以通过在其Validation.HasError属性返回true时增加TextBox控件本身的Margin属性来执行此操作。
在这种情况下,您可以将TextBox的上边距设置为与Validation.ErrorTemplate中Grid的第一行相同的高度:
<TextBox />
<TextBox Text="{Binding Username, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}">
<Validation.ErrorTemplate>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Row="1" BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder x:Name="Adorner"/>
</Border>
<TextBlock Grid.Row="0" Foreground="Red" Text="{Binding ErrorContent}"></TextBlock>
</Grid>
</ControlTemplate>
</Validation.ErrorTemplate>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<!-- increase the top margin of the TextBox in order for the error content not to overlap the control above -->
<Setter Property="Margin" Value="0 20 0 0" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
由于装饰器的渲染与装饰器绑定的UIElement的渲染无关,因此当装饰器可见时,TextBox无法自动调整其位置。这就是为什么你必须自己明确保留adorner元素的空间。
答案 1 :(得分:0)
另一种可能的方式是直接包含另一个元素进行错误显示,并根据 HasErrors
属性设置其可见性,因此可以自动调整其他元素的位置。
<TextBlock x:Name="TextBlockDate" DockPanel.Dock="Left" Text="{Binding Data}"/>
<TextBlock Foreground="Red" Text="{Binding ElementName=TextBlockData, Path=(Validation.Errors)[0].ErrorContent}" Visibility="{Binding Path=HasErrors, Converter={StaticResource BooleanToVisibilityConverter}}"/>