Binding Type – Relative Source in WPF

One of the most important concept of WPF / Silverlight is utilizing the power of Binding. So I will start with most asked question – Relative Source . Relative source is of following types,
1. Self
2. FindAncestor
3. Templated Parent
4. Previous

1. Self :

Self is generally useful when one wants to use the properties/values either of itself or of its Parent. Shown below are 2 examples to illustrate the same,

<Rectangle x:Name="rect" Height="100" Width="{Binding RelativeSource={RelativeSource Self},Path=Height}" Fill="Black"/>

 <Border Name="Parent1"
                  Width="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualWidth}"
                  Height="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualHeight}">

2. Find Ancestor :

This is useful to use the properties/values of any of its Parent. You can use this to Find the Ancestor with any level as shown below,

<Canvas Name="Parent0">
            <Border Name="Parent1"
                  Width="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualWidth}"
                  Height="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualHeight}">
                <Canvas Name="Parent2">
                   
                            <TextBlock FontSize="16" 
                   Margin="5" Text="Display the name of the ancestor"/>
                            <TextBlock FontSize="16" 
                     Margin="50" 
                Text="{Binding RelativeSource={RelativeSource  
                           FindAncestor,
                            AncestorType={x:Type Border}, 
                           AncestorLevel=1},Path=Name}" 
                           Width="200"/>
                       
                </Canvas>
            </Border>
        </Canvas>

In the above example we are using FindAncestor relative source to find Ancestor of Type Border and level 1 and use its Name value to be displayed in the textbox. Level indicates the amount of level you want to parse. Suppose you have a Logical tree of Canvas -> Border1 -> Canvas1 -> Border2 -> Canvas2 -> Border3 ->Canvas3-> Textbox then , when you specify the level (starting from 1) it will parse up . So if you want Border1 you want to write AncestorType={x:Type Border},AncestorLevel=3} . If you put anything other than what you actually have it wont throw any compile time exception and the value will not be displayed. An example for this can be found below ,

<Canvas Name="Parent0">
            <Border Name="Parent1"
                  Width="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualWidth}"
                  Height="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualHeight}">
                <Canvas Name="Parent2">
                    <Border Name="Parent3"
                 Width="{Binding RelativeSource={RelativeSource Self},
                Path=Parent.ActualWidth}"
                Height="{Binding RelativeSource={RelativeSource Self},
                   Path=Parent.ActualHeight}">
                        <Canvas Name="Parent4">
                            <TextBlock FontSize="16" 
                   Margin="5" Text="Display the name of the ancestor"/>
                            <TextBlock FontSize="16" 
                     Margin="50" 
                Text="{Binding RelativeSource={RelativeSource  
                           FindAncestor,
                            AncestorType={x:Type Border}, 
                           AncestorLevel=1},Path=Name}" 
                           Width="200"/>
                        </Canvas>
                    </Border>
                </Canvas>
            </Border>
        </Canvas>

3. Templated Parent :

This is typically used when you are creating a Control template (UI design) and you dont know what will be few values i.e few values will depend on Child properties , that time you can use Templated Parent as shown below,

<Window.Resources>
        <ControlTemplate x:Key="template">
            <Canvas>
                <Canvas.RenderTransform>
                    <RotateTransform Angle="20"/>
                </Canvas.RenderTransform>
                <Ellipse Height="100" Width="150" 
                     Fill="{Binding 
                RelativeSource={RelativeSource TemplatedParent},
                 Path=Background}">

                </Ellipse>
                <ContentPresenter Margin="35" 
                      Content="{Binding RelativeSource={RelativeSource  
                      TemplatedParent},Path=Content}"/>
            </Canvas>
        </ControlTemplate>
    </Window.Resources>

And for usage we can use it as below,

 <Canvas Name="Parent01">
            <Button   Margin="50" 
                  Template="{StaticResource template}" Height="0" 
                  Canvas.Left="0" Canvas.Top="0" Width="0">
                <TextBlock FontSize="22" Background="BurlyWood">Click me</TextBlock>
            </Button>
        </Canvas>

Difference between Templated Binding and Templated parent is TemplateBinding is evaluated at compile time at the contrast of the TemplatedParent which is evaluated just after the first run time

4. Previous :

This is the least which is used. This comes in Handy when you are working with values and you want to show the change with respect to the previous values, for example in stocks graphs or displaying results. You can use it as below,

<TextBlock FontSize="14" FontWeight="bold" Margin="20" 
            Text="{Binding RelativeSource={RelativeSource PreviousData}, 
                   Path=Value}"/>

Hope you have enjoyed 🙂

11 thoughts on “Binding Type – Relative Source in WPF

    • The RelativeSource is a markup extension that is used in particular binding cases when we try to bind a property of a given object to another property of the object itself, when we try to bind a property of a object to another one of its relative parents, when binding a dependency property value to a piece of XAML in case of custom control development and finally in case of using a differential of a series of a bound data. All of those situations are expressed as relative source modes. Do let me know if you have any further doubts !!!!

Leave a comment