Posts
58
Comments
399
Trackbacks
0
Binding to an Attached Property

Yesterday, I have some ideas in my mind on how to give out ValidationRule errors after the values passes the converter, and I was trying to see if I can use Attached Properties for that.

When trying to do this, one of the things I'd like to do was set a control's text to the Attached Property's value and that's when I realized that I don't know the syntax to do that.

A quick Google search yields some results; someone asked the same question and the answer suggested using parentheses.  The following example where the TextBox will display the row index the textbox is residing show how this works:

Bind to Grid.Row attached property

<Grid>

    <Grid.RowDefinitions>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="Auto"/>

    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>

        <ColumnDefinition/>

    </Grid.ColumnDefinitions>

    <TextBox Text="{Binding (Grid.Row),RelativeSource={RelativeSource Self}}"

             Height="23" Grid.Column="0" Grid.Row="0" VerticalAlignment="Top" />

    <TextBox Text="{Binding (Grid.Row),RelativeSource={RelativeSource Self}}"

             Height="23" Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" />

    <TextBox Text="{Binding (Grid.Row),RelativeSource={RelativeSource Self}}"

             Height="23" Grid.Column="0" Grid.Row="2" VerticalAlignment="Top" />

    <TextBox Text="{Binding (Grid.Row),RelativeSource={RelativeSource Self}}"

             Height="23" Grid.Column="0" Grid.Row="3" VerticalAlignment="Top"

             Name=”textBox4” />

</Grid>

You can also see that I didn't use Path=(Grid.Row), by default the first parameter is assigned to the Path property of the Binding class.

What about if we want to do it in code; it's very similar: 

Binding b = new Binding("(Grid.Row)");

b.Source = textBox4;

BindingOperations.SetBinding(textBox4, TextBox.TextProperty, b);

The binding path is the same; (Grid.Row) and the other important tidbit is that the source is the textbox itself.  This is logical since when assigning a value to an Attached Property, you're assigning that value for a given DependencyObject.  In this case, we want the text to be set to the Grid.Row attached property for that particular textbox too.

Verifying that it works, now I continue on with my class that implements the Attached Property.  However, since I need to refer to my class using XML namespace, how would the Path look?  The path has to use the namespace too, as the sample below shows:

 

<Grid xmlns:local="clr-namespace:BindingToAttachedProperty">

    <Grid.RowDefinitions>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="Auto"/>

        <RowDefinition Height="Auto"/>

    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>

        <ColumnDefinition/>

    </Grid.ColumnDefinitions>

    <TextBox Text="{Binding Path=(local:LocalClass.SomeValue),RelativeSource={RelativeSource Self}}"

             local:LocalClass.SomeValue="1"

             Height="23" Grid.Column="0" Grid.Row="0" Vertical.Alignment="Top" />

    <TextBox Text="{Binding (local:LocalClass.SomeValue),RelativeSource={RelativeSource Self}}"

             local:LocalClass.SomeValue="2"

             Name="textBox2"

             Height="23" Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" />

</Grid>

I found a weird condition in WPF; you can see that for the first TextBox, the Binding has the Path=, while the second one doesn't.  The sample above works, the first textbox will display 1, and the second textbox will display 2.  However, if you take out that Path= string, the example will not work; the BindingExpression specifies PathError.  I believe this is because without the first Path=, WPF doesn't know what is (local:LocalClass.SomeValue).  By specifying Path=, WPF compiles it correctly, and the subsequent encounter of (local:LocalClass.SomeValue) in textBox2 results in a correct interpretation.

OK, the XAML works; how to do it in code?  I tried all kinds of combination for the path, and could not get anything to work - it took me about 2 hours trying around and finally I got a solution.

Binding b = new Binding();

b.Path = new PropertyPath(LocalClass.SomeValueProperty);

b.Source = textBox2;

BindingOperations.SetBinding(textBox2, TextBox.TextProperty, b);

Most of the time, people will just create a new Binding instance, passing the string path in its constructor.  I could not get this to work; all types of string values that I tried results in PathError.  Finally, I took a good look at the Path property in the Binding class and found that one of the PropertyPath constructor accepts an object parameter that can be a DependencyProperty.

This would be my first 'New Thing I Learned' to document .  I'm sure I will look at this information again in the future, and I hope other people can benefit from this.

posted on Tuesday, January 15, 2008 12:53 PM Print
Comments
Gravatar
# re: Binding to an Attached Property
Matthias
2/2/2008 12:20 AM
This post is a life saver. I spent hours (literally) on this stupid binding hiccup.

Thank you, thank you, thank you.
Gravatar
# Thank you a lot!
Fame T.
10/14/2008 7:35 AM
This post helped me.
Gravatar
# re: Binding to an Attached Property
Jim
1/4/2009 4:50 PM
Very interesting - thanks for blogging this.
Gravatar
# re: Binding to an Attached Property
Peter
3/13/2009 8:44 AM
Thanks man!!!
Gravatar
# re: Binding to an Attached Property
Bob
4/7/2009 9:03 AM
You're the man!
Gravatar
# re: Binding to an Attached Property
devzi11a
4/23/2009 11:24 AM
are you a god?
Gravatar
# re: Binding to an Attached Property
Joe Gershgorin
7/12/2009 5:18 PM
You're amazing. Thanks, I was an hour and half into this problem.

My need was slightly different I needed to set a relative binding value to an attached behavior dependency property.

This ended up being the solution:

// Returns the first Popup control encountered on the upward path
// starting at the target element of the binding
var myBinding = new Binding
{
Mode = BindingMode.OneWay,
RelativeSource = new RelativeSource
{
AncestorLevel = 1,
AncestorType = typeof (Popup),
Mode = RelativeSourceMode.FindAncestor
}
};




BindingOperations.SetBinding(this, PopupControlProperty, myBinding);
Gravatar
# re: Binding to an Attached Property
Daniell
3/10/2010 8:36 PM
Very nice, helped me to my exact problem. This is a post I like, not much "blabla" straight to the point. Bravo!
Gravatar
# re: Binding to an Attached Property
rahul kapoor
3/22/2010 4:49 AM
good work.. MSdata man.
Gravatar
# re: Binding to an Attached Property
Brad
4/7/2010 7:04 AM
This must be for WPF because the same doesn't work for Silverlight 3. Been pulling my hair out to find a solution for this same problem in SL3.
Gravatar
# re: Binding to an Attached Property
JD
6/1/2010 2:01 AM
In regard to the little bug regarding the Path argument - I've also expereinced that issue when binding to indexed properties belonging to objects that are not defined in the default xml namespace - in other words custom classes.
Gravatar
# re: Binding to an Attached Property
Ian Randall
6/17/2010 3:48 PM
Beautiful... thank you!
Gravatar
# re: Binding to an Attached Property
Vordoom
8/3/2010 9:40 PM
Thank you! That's awesome!
It saved me alot of time!
Gravatar
# re: Binding to an Attached Property
krishna
12/7/2010 8:15 PM
awesome, exactly what i was looking for ;)
Gravatar
# re: Binding to an Attached Property
Nick
4/5/2011 12:09 PM
thumbs up - you saved me:)
Gravatar
# re: Binding to an Attached Property
Lijo
6/10/2011 1:25 AM
Can you please share the complete source code for this? A silverlight version will be more useful.
Gravatar
# re: Binding to an Attached Property
Steve
6/21/2011 7:59 AM
It was helpful and saved me some debugging - thanks. :)
Gravatar
# re: Binding to an Attached Property
Jon
11/26/2011 12:54 PM
Thank you!! Yes!! Banging my head against the wall for hours, now you got me past that one.
Gravatar
# re: Binding to an Attached Property
Jochen
2/9/2012 2:03 AM
Tip Top!!! Thx
Gravatar
# re: Binding to an Attached Property
Murugan
7/20/2012 4:58 AM
Hi
can u share the complete code then it is useful for me ... Good work keep it up...:)
Gravatar
# re: Binding to an Attached Property
Suresh Thotakura
8/19/2012 7:20 AM
Nice One, Thanks!
Gravatar
# re: Binding to an Attached Property
Alex
9/5/2012 4:30 AM
Thanks, just what I needed.

Post Comment

Title *
Name *
Email
Comment *