Question

I want to bind the Value of a custom AttachedProperty to the content of a ToolTip.

The binding works, but only on the second opening of the ToolTip. When the tooltip gets opened the first time, the binding has its FallbackValue.

Curiously it works with the "default" AttachedProperties like for example Grid.Row.

Can anyone explain that?

The code is quite simple:

<Button local:AttachedProperty.TestProperty="Now it works!" Content="Button">
    <Button.ToolTip>
        <ToolTip DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}">
            <TextBlock Text="{Binding (local:AttachedProperty.TestProperty), FallbackValue=&quot;It doesn't work&quot;}" />
        </ToolTip>
    </Button.ToolTip>
</Button>

The code of the AttachedProperty:

public static class AttachedProperty
{
    public static readonly DependencyProperty TestPropertyProperty = DependencyProperty.RegisterAttached
    (
        "TestProperty",
        typeof(string),
        typeof(AttachedProperty),
        new FrameworkPropertyMetadata
        (
            string.Empty,
            FrameworkPropertyMetadataOptions.Inherits
        )
    );

    public static string GetTestProperty(FrameworkElement target)
    {
        return (string)target.GetValue(TestPropertyProperty);
    }

    public static void SetTestProperty(FrameworkElement target, string value)
    {
        target.SetValue(TestPropertyProperty, value);
    }
}

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

EDIT 1: Solution and a new problem:

I found out it works, when I define the namespace "local" again within the tooltip:

<ToolTip xmlns:local="clr-namespace:Test" DataContext=...

BUT

If you want to want to do this within a style, you get the error

"XMLNamespace", "Assembly" or "ClrNamespace" not found in Mapping Expression

The XML-Code for my new Test-Project is:

<Grid x:Name="LayoutRoot">
    <Grid.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="ToolTip">
                <Setter.Value>
                    <ToolTip xmlns:local="clr-namespace:Test" DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}" >
                <TextBlock  Text="{Binding (local:AttachedProperty.TestProperty), FallbackValue=&quot;It doesn't work&quot;}" />
            </ToolTip>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>

    <Button local:AttachedProperty.TestProperty="Now it works!" Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
Was it helpful?

Solution

I've added some trace output in a PropertyChangedCallback (and removed the Inherits flag since it is useless here):

public static readonly DependencyProperty TestPropertyProperty =
    DependencyProperty.RegisterAttached(
        "TestProperty",
        typeof(string),
        typeof(AttachedProperty),
        new FrameworkPropertyMetadata(
            string.Empty,
            (o, e) => Trace.TraceInformation("Setting TestProperty = \"{1}\" on {0}", o, e.NewValue))
);

Visual Studio output proves that the property has been set before the binding complains that it could not be found:

ToolTipAttachedProperty.vshost.exe Information: 0 : Setting TestProperty = "Now it works!" on System.Windows.Controls.Button
System.Windows.Data Warning: 40 : BindingExpression path error: '(local:AttachedProperty.TestProperty)' property not found on 'object' ''Button' (Name='')'. BindingExpression:Path=(local:AttachedProperty.TestProperty); DataItem='Button' (Name=''); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

You should perhaps send this to Microsoft.

EDIT: Referring to your edit about putting the ToolTip in a Style. You could write this:

<Grid.Resources>
    <ToolTip xmlns:local="clr-namespace:Test" x:Key="ButtonToolTip"
             DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}">
        <TextBlock Text="{Binding (local:AttachedProperty.TestProperty), FallbackValue=&quot;It doesn't work&quot;}" />
    </ToolTip>
    <Style TargetType="Button">
        <Setter Property="ToolTip" Value="{StaticResource ButtonToolTip}"/>
    </Style>
</Grid.Resources>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top