0

我在如何为垂直 StackPanel 中的 TextBox 元素显示验证错误时遇到问题。我正在尝试在 TextBox 下方显示错误消息。

我有这个错误模板:

    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <StackPanel>
                        <AdornedElementPlaceholder />
                        <ItemsControl ItemsSource="{Binding}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding (ValidationError.ErrorContent)}" Foreground="Red" Margin="5"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

如果我在 TextBox 下方有足够的空白空间,则错误会很好地显示,但在 StackPanel(例如)中,由于装饰层,它不会在有一些错误消息时为错误消息添加额外的边距或填充。

根据此消息来源,预计会如此:

请注意,Validation.ErrorTemplate 将显示在装饰层上。装饰层中的元素呈现在其余可视元素之上,当布局系统测量和排列装饰元素层上的控件时,它们不会被考虑。

如何显示验证错误消息,以便它们不会显示在 StackPanel 中的其他元素上?

4

2 回答 2

2

您还可以考虑将您的错误模板包含在 TextBox 的模板中。类似的东西(当然可以改进):

<Style x:Key="eTextBox" TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <StackPanel>
                    <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="1" Padding="2">
                        <ScrollViewer Name="PART_ContentHost" Focusable="False" 
                                    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                                    ScrollViewer.VerticalScrollBarVisibility="Hidden"
                                    Background="#00FFFFFF" />
                    </Border>
                    <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(Validation.Errors)}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding (ValidationError.ErrorContent)}" Foreground="Red" Margin="5"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </StackPanel>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这样,ItemsControl 被考虑用于布局计算。

于 2015-04-27T14:05:36.680 回答
0

好的,我找到了转换器的解决方案。我最终得到了与此类似的样式:

    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="10" />
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <StackPanel>
                        <AdornedElementPlaceholder />
                        <ItemsControl ItemsSource="{Binding}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding (ValidationError.ErrorContent)}" Foreground="Red" Margin="0,5"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Trigger.Setters>
                    <Setter Property="Margin" Value="{Binding (Validation.Errors).Count, RelativeSource={RelativeSource Self}, Converter={StaticResource ErrorsToMarginConverter}}"/>
                </Trigger.Setters>
            </Trigger>
        </Style.Triggers>
    </Style>

和转换器:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is int)
        {
            var errors = (int)value;
            return new Thickness(10, 10, 10, (errors * 20));
        }

        return value;
    }
于 2015-04-27T13:40:20.763 回答