Моя проблема в том, что я не получаю текст 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);
Шаблон, кажется, работает (я вижу эллипс с "!"), Но я не вижу моего сообщения об исключении.
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>
Validation.Errors
от украшенного элемента также применяется к TemplatedAdorner
, но быстрый тест с Snoop показывает, что это не так. Хороший улов.
Validation.Errors
по-прежнему принадлежит TextBox
(доступ к которому осуществляется через свойство AdornedElement
объекта AdornedElementPlaceholder
. Я думаю, что это свойство предназначено для такого сценария.
Binding
в вашемErrorTemplate
, попробуйте использовать{RelativeSource Self}
вместо{RelativeSource TemplatedParent}
.