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 に答える