ControlTemplate Binding TextBox внутри ErrorTemplate

1

Моя проблема в том, что я не получаю текст ToolTip, который вызывается SetterException моего объекта привязки.

У меня есть ControlTemplate, как это:

<ControlTemplate x:Key="textBoxErrorTemplate" >
    <Grid Margin="-15,5,0,0" ToolTip="{Binding RelativeSource={RelativeSource TemplatedParent},Path=(Validation.Errors)[0].ErrorContent}">
        <Ellipse StrokeThickness="0" Fill="Red" Width="{TemplateBinding FontSize}" Height="{TemplateBinding FontSize}" />
        <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center"  />                               
    </Grid>
</ControlTemplate>

Я также пробовал

ToolTip="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"
ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}},Path=(Validation.Errors)[0].ErrorContent}"

Мой TextBox выглядит следующим образом:

<TextBox Grid.Row="1" Grid.Column="1" Name="tbMin" SourceUpdated="tb_SourceUpdated" Validation.ErrorTemplate="{StaticResource textBoxErrorTemplate}"/>

Я связываю источник данных с кодом следующим образом:

Binding bindMinString = new Binding("MinString");
        bindMinString.Source = curStep;
        bindMinString.NotifyOnSourceUpdated = true;
        bindMinString.ValidatesOnExceptions = true;
        bindMinString.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        tbMin.SetBinding(TextBox.TextProperty, bindMinString);

Шаблон, кажется, работает (я вижу эллипс с "!"), Но я не вижу моего сообщения об исключении.

  • 0
    Для Binding в вашем ErrorTemplate , попробуйте использовать {RelativeSource Self} вместо {RelativeSource TemplatedParent} .
  • 0
    Я только что обновил то, что тоже попробовал, и не сработало. Так не твоя идея.
Показать ещё 2 комментария
Теги:
wpf
binding

1 ответ

0
Лучший ответ

DataContext не может течь из визуального дерева в ErrorTemplate. Поэтому использование RelativeSource или ElementName для таргетинга на внешний визуальный элемент не будет работать здесь. Единственная ссылка здесь - AdornedElementPlaceholder, даже если вам не нужно ее добавлять, вы можете установить Visibility на Collapsed. По крайней мере, это лучший способ настроить таргетинг на элемент, на который применяется ErrorTemplate. Это свойство называется AdornedElement и это точка доступа, в которой вы нуждаетесь. Вот рабочий код:

<Grid Margin="-15,5,0,0" 
      ToolTip="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent,
                        ElementName=a}">
    <AdornedElementPlaceholder Name="a" Visibility="Collapsed"/>
    <Ellipse StrokeThickness="0" Fill="Red" 
       Width="{TemplateBinding FontSize}" Height="{TemplateBinding FontSize}" />
    <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" FontWeight="Bold" 
        Foreground="White" HorizontalAlignment="Center"  />
</Grid>

ОБНОВЛЕНИЕ:

Я только что нашел еще одно прямое решение. На самом деле неявный DataContext внутри ErrorTemplate установлен в ReadonlyObservableCollection<ValidationError> который является значением Validation.Errors, поэтому код может быть намного проще:

<Grid Margin="-15,5,0,0" 
      ToolTip="{Binding [0].ErrorContent}">
    <Ellipse StrokeThickness="0" Fill="Red" 
       Width="{TemplateBinding FontSize}" Height="{TemplateBinding FontSize}" />
    <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" FontWeight="Bold" 
        Foreground="White" HorizontalAlignment="Center"  />
</Grid>
  • 0
    Как ни странно, образец MSDN, с которым я ознакомился, предположил, что Validation.Errors от украшенного элемента также применяется к TemplatedAdorner , но быстрый тест с Snoop показывает, что это не так. Хороший улов.
  • 0
    @MikeStrobel здесь Validation.Errors по-прежнему принадлежит TextBox (доступ к которому осуществляется через свойство AdornedElement объекта AdornedElementPlaceholder . Я думаю, что это свойство предназначено для такого сценария.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню