Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

From code, how can you create a binding to a property on an object stored in an attached property?

We have an inheriting attached property which stores an object. Further down the visual tree, we want to bind to a property on that object from code.

Normally we construct the Path portion of a binding like so...

var someBinding = new Binding()
{
    Path = new PropertyPath(AttachedPropertyOwner.SomeAttachedProperty),
    RelativeSource = new RelativeSource(RelativeSourceMode.Self)
}; 

That works, but we now want a property of the object stored in SomeAttachedProperty. I take it we're supposed to use the string representation?

Also, while researching this, I found this on MSDN: Property Path Syntax

The concerning part is down under the heading 'PropertyPathInCode'

If you construct a PropertyPath from a DependencyProperty, that PropertyPath is not usable as a Binding.Path, it is only usable for animation targeting. The Path value for the constructed PropertyPath from a DependencyProperty is the string value (0), which is a sentinel value used by the binding engine for an invalid path.

...which doesn't make sense to me since it appears to work fine. Am I missing something? Have we been doing all of our code bindings wrong?

Update

Reading the MSDN documentation comment (which I missed was Silverlight, but I don't think matters in this case), it says you can't use a Dependency Property. However, it says you can use a DependencyProperty identifier, the identifier being what's returned from the Register methods.

In other words, I think what they're saying is what we're doing is valid...

var someBinding = new Binding()
{
    Path = new PropertyPath(CarClass.WheelCountProperty)
}; 

...but this is not.

var someBinding = new Binding()
{
    Path = new PropertyPath(MyCarInstance.WheelCount)
}; 

Seemingly confirming this, under the hood, Reflector shows it's essentially just doing this...

public PropertyPath(object value)
: this("(0)", new [] { value })
{
    ....
}

...so I think that scare was a red herring.

I think that also means I can do what I'm after like this...

Path = new PropertyPath("(0).(1)",
    SomeClass.SomeAttachedProperty,
    SomeOtherClass.SomeOtherAttachedProperty)

...which gets the value of the second attached property from the object stored in the first attached property.

like image 461
Mark A. Donohoe Avatar asked Oct 16 '25 16:10

Mark A. Donohoe


1 Answers

I just confirmed my earlier suspicion was correct. Here's all you have to do to bind to an attached property on the value stored in another attached property...

Path = new PropertyPath("(0).(1)",
    SomeClass.SomeAttachedProperty,
    SomeOtherClass.SomeOtherAttachedProperty)

As stated in the update, for simple properties, this is also valid.

Path = new PropertyPath(SomeClass.SomeAttachedProperty)

...which essentially is the equivalent of this...

Path = new PropertyPath("(0)",
    SomeClass.SomeAttachedProperty)
like image 83
Mark A. Donohoe Avatar answered Oct 19 '25 07:10

Mark A. Donohoe