I'm working with WPF and I want to use attached properties to work with some styling things in the validation of the controls (my example of the problem is really simple, binding a simple text).
This is my attached property:
public class ToolTipExtension
{
public static readonly DependencyProperty ShowToolTipProperty = DependencyProperty.RegisterAttached(
"ShowToolTip", typeof(string), typeof(ToolTipExtension), new PropertyMetadata("Deffault"));
public static void SetShowToolTip(DependencyObject element, string value)
{
element.SetValue(ShowToolTipProperty, value);
}
public static string GetShowToolTip(DependencyObject element)
{
return (string) element.GetValue(ShowToolTipProperty);
}
}
I have a simple style dictionary like this
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:at="clr-namespace:CarpetaTecnicaWPF.AttachedProperties"
>
<Style TargetType="{x:Type TextBox}" x:Key="Blah" >
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(at:ToolTipExtension.ShowToolTip)}" FontSize="50"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
As you can see, I'm trying to bind the Text
property to my attached property.
In my Page
, I'm using the style like this:
<TextBox Style="{StaticResource Blah}" at:ToolTipExtension.ShowToolTip="Prueba?"/>
The thing is, the value Prueba?
does not appear. When I inspect the tree, I see this:
But in runtime, the result of the binding is Deffault
What am I doing wrong?
Your binding is incorrect.
The TemplatedParent
in this case is not what you actually need. The ControlTemplate
for the error is not applied to the text box itself, it's a stand-alone control template. So you are just getting a default value from a wrong FrameworkElement
.
To access the text box your error template is applied to, you need to use the AdornedElementPlaceholder
in your ControlTemplate
. From that AdornedElementPlaceholder
, you can access your text box via the AdornedElement
property.
Here is an example:
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<AdornedElementPlaceholder x:Name="adorner"/>
<TextBlock Text="{Binding ElementName=adorner, Path=AdornedElement.(at:ToolTipExtension.ShowToolTip)}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>