简体   繁体   中英

Strange behavior for WPF attached property and binding

I am trying to register an WPF attached property on a grid control, however, I met very strange behavior today:

public static class MyClass
{
    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.RegisterAttached("MyProperty", typeof(string),
        typeof(MyClass), null);

    public static string GetMyProperty(DependencyObject d)
    {
        return (string)d.GetValue(MyPropertyProperty);
    }

    public static void SetMyProperty(DependencyObject d, string value)
    {
        d.SetValue(MyPropertyProperty, value); //<-- set breakpoint here
    }
}

XAML:

<GridControl local:MyClass.MyProperty="My Name">
...
</GridControl>

when I wrote like this, the attached property's setter never gets executed. and value never be set. but I can snoop into the grid and found the attached property is attached with an empty value.

but when I change the attached property name to:

    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.RegisterAttached("xxxMyProperty", typeof(string),
        typeof(MyClass), null);

ie use a different name other than MyProperty. then the breakpoint can be hit! and value can be set!

Moreover, when I change the attached property as:

    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.RegisterAttached("MyProperty", typeof(string),
        typeof(UIElement), null);

ie change the owner type to UIElement, then I can also hit the breakpoint, just wondering why?

However, when I setup a binding in XAML instead of a string constant, each case above will got an exception saying A 'Binding' can only be set on a DependencyProperty of a DependencyObject

Binding XAML example:

<GridControl local:MyClass.MyProperty="{Binding MyStringValue}">
...
</GridControl>

Does anyone met this strange behavior before? What am I missing in my case? Thanks in advance for the reply!

If you are referring to the SetMyProperty method as the 'setter', then you should know that these methods are simply 'helper' methods for you to use. The Framework does not generally use these methods.

If however, you are saying that you would like to know when the value changes, then there is another way of doing this. Add a PropertyChangedCallback handler to the declaration of the property:

public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.RegisterAttached("MyProperty", typeof(string), typeof(MyClass), 
    new UIPropertyMetadata(default(string.Empty), OnMyPropertyChanged));

public static void OnMyPropertyChanged(DependencyObject dependencyObject, 
    DependencyPropertyChangedEventArgs e)
{
    string myPropertyValue = e.NewValue as string;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM