Can't bind an attached property to another dependency property
Asked Answered
V

1

10

I' writing a control library. In this library there are some custom panels which are populated with user UIElements. Since every child element in my lib must have a "Title" property, I wrote the following:

// Attached properties common to every UIElement
public static class MyLibCommonProperties
{
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.RegisterAttached( 
            "Title", 
            typeof(String),
            typeof(UIElement), 
            new FrameworkPropertyMetadata(
                "NoTitle", new PropertyChangedCallback(OnTitleChanged))
            );

    public static string GetTitle( UIElement _target )
    {
        return (string)_target.GetValue( TitleProperty );
    }

    public static void SetTitle( UIElement _target, string _value )
    {
        _target.SetValue( TitleProperty, _value );
    }

    private static void OnTitleChanged( DependencyObject _d, DependencyPropertyChangedEventArgs _e )
    {
       ...
    }
}

Then, if I write this:

<dl:HorizontalShelf>
    <Label dl:MyLibCommonProperties.Title="CustomTitle">1</Label>
    <Label>1</Label>
    <Label>2</Label>
    <Label>3</Label>
</dl:HorizontalShelf>

everything works fine and the property gets the specified value, but if I try to bind that property to some other UIElement DependencyProperty like this:

<dl:HorizontalShelf>
    <Label dl:MyLibCommonProperties.Title="{Binding ElementName=NamedLabel, Path=Name}">1</Label>
    <Label>1</Label>
    <Label>2</Label>
    <Label Name="NamedLabel">3</Label>
</dl:HorizontalShelf>

an exception would be thrown: "A 'Binding' cannot be set on the 'SetTitle' property of type 'Label'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject."

What am I missing? Binding seems to work fine if instead of binding to "Name" I bind to some other attached property defined in MyLibCommonProperties.

Thanks in advance.

Vickery answered 11/11, 2011 at 10:49 Comment(3)
Hi, MyLibCommonProperties must derive from DependecyObjectPolypary
Just a guess, but change your Get/SetTitle first parameters to DependencyObject, not UIElement. Also while registering your Attache property the third parameter must be the owner of the attached property, not the desired target. Change it to MyLibCommonProperties.Interlace
What is HorizontalShelf? Have you tried it in a StackPanel or similar built-in control instead? Everything else seems fine. I can only assume HorizontalShelf is a custom control that does not recognize its children as logical children. See here: kentb.blogspot.com/2008/10/customizing-logical-children.htmlVadavaden
B
16

Replace the UIElement in your DependencyProperty definition to MyLibCommonProperties

public static readonly DependencyProperty TitleProperty =
    DependencyProperty.RegisterAttached( 
        "Title", 
        typeof(String),
        typeof(MyLibCommonProperties), // Change this line
        new FrameworkPropertyMetadata(
            "NoTitle", new PropertyChangedCallback(OnTitleChanged))
        );

I think it might be because the binding implicitly uses the parent class specified to call SetTitle() so it is calling Label.SetTitle() instead of MyLibCommonProperties.SetTitle()

I had the same issue with some custom TextBox properties. If I used typeof(TextBox) then I couldn't bind to the value, but if I used typeof(TextBoxHelpers) then I could

Brooklynese answered 11/11, 2011 at 14:11 Comment(2)
Rachel this is not the first time one of your answers has helped me! (and I'm sure it won't be that last). Even after almost a decade.Desma
@UuDdLrLrSs Oh wow I can't believe it's been almost a decade! Now I feel old lol I'm very glad my answers are still useful though! :)Brooklynese

© 2022 - 2024 — McMap. All rights reserved.