A lot of articles those are talking about binding and sources, and how to bind
properties each other using StaticResources, DynamicResources, although you can
find information about the RelativeSource and its use cases but not with more
details even in Microsoft documentations. In this article, I will expose the use
cases of the RelativeSources 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. I will expose all of those cases one by one.

1. Mode Self:

Imagine this case, a rectangle that we want that its height is always equal to
its width, a square let's say. We can do this using the element name

<Rectangle
Fill="Red"
Name="rectangle" Height="100"
Stroke="Black" Canvas.Top="100"
Canvas.Left="100" Width="{Binding
ElementName=rectangle, Path=Height}"/>
But in this above case we are obliged to indicate the name of the binding
object, namely the rectangle. We can reach the same purpose differently using
the RelativeSource

<Rectangle
Fill="Red"
Height="100" Stroke="Black" Width="{Binding
RelativeSource={RelativeSource
Self}, Path=Height}"/>
For that case we are not obliged to mention the name of the binding object and
the Width will be always equal to the Height whenever the height is changed.

If you want to parameter the Width to be the half of the height then you can do
this by adding a converter to the Binding markup extension.
Let's imagine another case now:

<TextBlock
Width="{Binding
RelativeSource={RelativeSource
Self}, Path=Parent.ActualWidth}"/>
The above case is used to tie a given property of a given element to one of its
direct parent ones as this element holds a property that is called Parent. This
leads us to another relative source mode which is the FindAncestor one.

2. Mode FindAncestor

In this case, a property of a given element will be tied to one of its parents,
Of Corse. The main difference with the above case is the fact that, it's up to
you to determine the ancestor type and the ancestor rank in the hierarchy to tie
the property. By the way try to play with this piece of XAML

<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=2},Path=Name}"Width="200"/>
</Canvas>
</Border>
</Canvas>
</Border>
</Canvas>
The above situation is of two TextBlock elements those are embedded within a
series of borders and canvas elements those represent their hierarchical
parents. The second TextBlock will display the name of the given parent at the
relative source level.

So try to change AncestorLevel=2 to AncestorLevel=1 and see what happens. Then
try to change the type of the ancestor from AncestorType=Border to AncestorType=Canvas
and see what's happens.

The displayed text will change according to the Ancestor type and level. Then
what's happen if the ancestor level is not suitable to the ancestor type? This
is a good question, I know that you're about to ask it. The response is no
exceptions will be thrown and nothings will be displayed at the TextBlock level.

3. TemplatedParent

This mode enables tie a given ControlTemplate property to a property of the
control that the ControlTemplate is applied to. To well understand the issue
here is an example bellow

</Ellipse>
<ContentPresenter
Margin="35"
Content="{Binding
RelativeSource={RelativeSource
TemplatedParent},Path=Content}"/>
</Canvas>
</ControlTemplate>
</Window.Resources>
<Canvas
Name="Parent0">
<Button
Margin="50"
Template="{StaticResource
template}"
Height="0"
Canvas.Left="0"
Canvas.Top="0"
Width="0">
<TextBlock
FontSize="22">Click
me</TextBlock>
</Button>
</Canvas>
If I want to apply the properties of a given control to its control template
then I can use the TemplatedParent mode. There is also a similar one to this
markup extension which is the TemplateBinding which is a kind of short hand of
the first one, but the TemplateBinding is evaluated at compile time at the
contrast of the TemplatedParent which is evaluated just after the first run
time. As you can remark in the bellow figure, the background and the content are
applied from within the button to the control template.

4. PreviousData

This is the most ambiguous and the less used mode of the RelativeSource, I mean
the PreviousData one. The PreviousData is used for particular cases. Its purpose
is to tie the given property to another property with a particular assignment; I
mean it assigns the previous value of the property to the bound one. In other
word, if you have a TextBox that has a text property and another control that
has a value property that holds data. Say that value is actually 5 and it was 3
just before. The 3 is assigned to the text property of the TextBox and not 5.
This leads to the idea that this kind of RelativeSource is frequently used with
the items controls.

To understand the phenomenon of the RelativeSource let's expose this sample. I
will add an ItemsControl into the scene and I will aliment it from a custom
collection

<Grid><ItemsControl></ItemsControl>
</Grid>
This ItemsControl is alimented using this collection:

Second, the DataTemplate is used to present the data as a border; the border
height is bound to the Value of the item class to reflect the Values that the
collection holds. The same border includes a TextBlock that displays the Value
of the Item object.

For more information about te DateTemplate please refer to this MSDN link