Search code examples
c#wpfxaml

Why default value of attached property is not shown?


I want a TextBlock to show the default value of an attached property, but it doesn't work.

XAML

<TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=MyData}" />

Attached Property

public class MyDependencyObject
{
    public static readonly DependencyProperty MyDataProperty =
        DependencyProperty.RegisterAttached("MyData", typeof(string), typeof(TextBlock),
            new FrameworkPropertyMetadata("MyDependencyObject"));


    public static string GetMyData(DependencyObject dpo)
    {
        return (string)dpo.GetValue(MyDataProperty);
    }

    public static void SetMyData(DependencyObject dpo, string value)
    {
        dpo.SetValue(MyDataProperty, value);
    }
}

When I set MyData's value, it works well.

<TextBlock local:MyDependencyObject.MyData="Test"
           Text="{Binding RelativeSource={RelativeSource Self}, Path=MyData}" />

Solution

  • Data binding to an attached property requires a Path in parentheses, see PropertyPath for Objects in Data Binding:

    <TextBlock Text="{Binding RelativeSource={RelativeSource Self},
                              Path=(local:MyDependencyObject.MyData)}"/>
    

    The attached property declaration must use the declaring class as ownerType argument to RegisterAttached

    public class MyDependencyObject
    {
        public static readonly DependencyProperty MyDataProperty =
            DependencyProperty.RegisterAttached(
                "MyData",
                typeof(string),
                typeof(MyDependencyObject), // here
                new FrameworkPropertyMetadata("MyDependencyObject"));
    
        public static string GetMyData(DependencyObject obj)
        {
            return (string)obj.GetValue(MyDataProperty);
        }
    
        public static void SetMyData(DependencyObject obj, string value)
        {
            obj.SetValue(MyDataProperty, value);
        }
    }
    

    Although the attached property was never explicitly set on the TextBlock, it will show the "MyDependencyObject" default value.