Перекрытие шаблона контроля валидации WPF

У меня есть пользовательский элемент управления с шаблоном элемента управления, чтобы показать ошибки проверки, шаблон проверки:

<ControlTemplate x:Key="TextBoxPropertyValidationTemplate">
        <StackPanel>
            <Border BorderBrush="Red" BorderThickness="1">
                <AdornedElementPlaceholder x:Name="MyAdorner" />
            </Border>

            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Image Grid.Column="0" MaxHeight="16" MaxWidth="16"
                       Source="{Binding Source={StaticResource ValidationIcon}, Converter={StaticResource UriConverter}}" 
                       Margin="1" RenderOptions.BitmapScalingMode="HighQuality"
                       VerticalAlignment="Center" HorizontalAlignment="Center" />
                <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left"
                           Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
                           TextWrapping="Wrap" Grid.Column="1" FontSize="10" Foreground="Red" />
            </Grid>

        </StackPanel>
    </ControlTemplate>

И я не могу обойти довольно раздражающую проблему, которая выглядит так:

Проверка

Я пытался поэкспериментировать с полями в пользовательском элементе управления и в шаблоне, а также с некоторым значением Height=Auto и т. Д., Но все это не очень помогает. Любые идеи кто-нибудь?

Если это помогает, основной пользовательский элемент управления (который объединяет элементы с проверкой) находится в TabItem с AdornerDecorator.

Любая помощь приветствуется.

2 ответа

Решение

Я бы сказал, что это потому, что ваше сообщение об ошибке на AdornerLayer, который не участвует в том же макете, что и ваш элемент управления. MSDN говорит, что "рендеринг рекламодателя не зависит от рендеринга элемента UIE, с которым он связан". и именно поэтому сообщение просто помещено поверх всего.

Вы можете поместить текст ошибки в исходный шаблон, скрыть его на основе Validation.HasError и таким образом включить его в процесс верстки.

Но изменение макета элемента управления может быть не лучшим способом, если возникает ошибка проверки. Вы можете рассмотреть возможность предоставления дополнительной информации в подсказке.

В качестве альтернативы, вместо использования ControlTemplate, вы могли бы поместить сообщение об ошибке TextBlock рядом с TextBox и установить его свойство Text, связывающее ErrorContent TextBox.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox x:Name="txtName" Grid.Row="0">
        <TextBox.Text>
            <Binding Path="Name" NotifyOnValidationError="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <common:RequiredFieldValidationRule/>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBlock Grid.Row="1" Text="{Binding ElementName=txtName,Path=(Validation.Errors)[0].ErrorContent}"
               Visibility="{Binding ElementName=txtName,Path=Validation.HasError,Converter=...}" />
</Grid>
Другие вопросы по тегам