Stopbyte

What is the use of RelativeSource in WPF Binding?

Is there any specific Use of RelativeSource in WPF? Or is it just like any other Binding source?

These are the only uses of RelativeSource that I know of in WPF:

– Getting an ancestor’s property:

{Binding Path=PathToProperty,
        RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}

– Binding to another property on the object:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}

– Bind to a property on the templated parent:

{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}

OR

{TemplateBinding Path=PathToProperty}

P.S. those last two options are identical so you may use anyone of them.

Depending on the Mode property of RelativeSource these are the possible uses of the property on any given WPF control:

  • PreviousData make you to bind the previous data item in the list of data items that displayed;

Binding RelativeSource={ RelativeSource Mode=PreviousData, AncestorType={x:Type ItemType}}...

  • TemplatedParent it’s like element exists in data bound:

Binding RelativeSource={ RelativeSource Mode=TemplatedParent, AncestorType={x:Type ItemType}}..

  • Self It’s used to bind a property of the same control (or element) to one of it’s own properties. e.g. a useful case is making width and height values identical:

Binding Path=Width, RelativeSource={ RelativeSource Mode=Self, AncestorType={x:Type ItemType}}...

  • FindAncestor You can use this property value to bind an ancestor of a specific type or its sub-class, FindAncestor can be used to specify the parent of any level of ancestry.

Binding RelativeSource={ RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}}...

Hope that helps!

  • As suggested in the first answer, here is an example of a rectangle using the binding to make the Width and Height Identical for the control:

      <Rectangle x:Name="MyRectangle" Fill="Yellow" Height="250" Stroke="Red" Width="{Binding ElementName=rectangle, Path=Height}"/>
    

As you can see in the example above, The Width of the rectangle is bound to its height. and for that we are using regular Binding through ElementName.

  • Pros. of using that method:
    Well nothing makes it different from using other binding techniques as far as I know. When it comes to performance etc. So nothing special.

  • Cons. though:
    Apparently, you have to name your control/element before using it. in the example above we used “x:Name="MyRectangle"” and we referred to that name through the binding.
    It’s not dynamic, whenever you change the name of your control, you’ll have to update the binding’s ElementName attribute.

  • Thus;
    We are using RelativeSource, Relative Source is by far very dynamic in similar situations… no need to name your controls to use them… and in fact you don’t need to know your controls in order to be able to bind to any of their properties. all you need is to know what’s their “relation” to the current control you are binding to.

  • We end up with something like this:

      <Rectangle Fill="Yellow" Height="250" Stroke="Red" Width="{Binding RelativeSource={RelativeSource Self}, Path=Height}"/>
    

Another use case would be even binding to the parent of the control, or one of its ancestors:

  • Like this:

      <Rectangle Fill="Yellow" Height="250" Stroke="Red" Width="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualHeight}"/>
    

As you can see in the example above, we are actually binding our rectangle’s Width to the ActualHeight of its parent, through RelativeSource.

Quoting what @Sine said, so to sum up everything:

We use RelativeSource to dynamically bind two properties together. When using RelativeSource it doesn’t really matter to know the source element we are binding from but all we have to know is their relation to the current (bound to) element (i.e. parent or child, their ancestry level) and/or its type (e.g. TextBox, Grid, Panel…etc) .

Hope that helps.