[.net] How do I use WPF bindings with RelativeSource?

How do I use RelativeSource with WPF bindings and what are the different use-cases?

This question is related to .net wpf xaml data-binding relativesource

The answer is


If you want to bind to another property on the object:

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

If you want to get a property on an ancestor:

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

If you want to get a property on the templated parent (so you can do 2 way bindings in a ControlTemplate)

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

or, shorter (this only works for OneWay bindings):

{TemplateBinding Path=PathToProperty}

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

The default attribute of RelativeSource is the Mode property. A complete set of valid values is given here (from MSDN):

  • PreviousData Allows you to bind the previous data item (not that control that contains the data item) in the list of data items being displayed.

  • TemplatedParent Refers to the element to which the template (in which the data-bound element exists) is applied. This is similar to setting a TemplateBindingExtension and is only applicable if the Binding is within a template.

  • Self Refers to the element on which you are setting the binding and allows you to bind one property of that element to another property on the same element.

  • FindAncestor Refers to the ancestor in the parent chain of the data-bound element. You can use this to bind to an ancestor of a specific type or its subclasses. This is the mode you use if you want to specify AncestorType and/or AncestorLevel.


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

The default attribute of RelativeSource is the Mode property. A complete set of valid values is given here (from MSDN):

  • PreviousData Allows you to bind the previous data item (not that control that contains the data item) in the list of data items being displayed.

  • TemplatedParent Refers to the element to which the template (in which the data-bound element exists) is applied. This is similar to setting a TemplateBindingExtension and is only applicable if the Binding is within a template.

  • Self Refers to the element on which you are setting the binding and allows you to bind one property of that element to another property on the same element.

  • FindAncestor Refers to the ancestor in the parent chain of the data-bound element. You can use this to bind to an ancestor of a specific type or its subclasses. This is the mode you use if you want to specify AncestorType and/or AncestorLevel.


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

The default attribute of RelativeSource is the Mode property. A complete set of valid values is given here (from MSDN):

  • PreviousData Allows you to bind the previous data item (not that control that contains the data item) in the list of data items being displayed.

  • TemplatedParent Refers to the element to which the template (in which the data-bound element exists) is applied. This is similar to setting a TemplateBindingExtension and is only applicable if the Binding is within a template.

  • Self Refers to the element on which you are setting the binding and allows you to bind one property of that element to another property on the same element.

  • FindAncestor Refers to the ancestor in the parent chain of the data-bound element. You can use this to bind to an ancestor of a specific type or its subclasses. This is the mode you use if you want to specify AncestorType and/or AncestorLevel.


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

The default attribute of RelativeSource is the Mode property. A complete set of valid values is given here (from MSDN):

  • PreviousData Allows you to bind the previous data item (not that control that contains the data item) in the list of data items being displayed.

  • TemplatedParent Refers to the element to which the template (in which the data-bound element exists) is applied. This is similar to setting a TemplateBindingExtension and is only applicable if the Binding is within a template.

  • Self Refers to the element on which you are setting the binding and allows you to bind one property of that element to another property on the same element.

  • FindAncestor Refers to the ancestor in the parent chain of the data-bound element. You can use this to bind to an ancestor of a specific type or its subclasses. This is the mode you use if you want to specify AncestorType and/or AncestorLevel.


Here's a more visual explanation in the context of a MVVM architecture:

enter image description here


Here's a more visual explanation in the context of a MVVM architecture:

enter image description here


Here's a more visual explanation in the context of a MVVM architecture:

enter image description here


Here's a more visual explanation in the context of a MVVM architecture:

enter image description here


Bechir Bejaoui exposes the use cases of the RelativeSources in WPF in his article here:

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.

  1. 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.

  1. 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

<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>
    <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.


Bechir Bejaoui exposes the use cases of the RelativeSources in WPF in his article here:

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.

  1. 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.

  1. 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

<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>
    <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.


Bechir Bejaoui exposes the use cases of the RelativeSources in WPF in his article here:

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.

  1. 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.

  1. 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

<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>
    <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.


Bechir Bejaoui exposes the use cases of the RelativeSources in WPF in his article here:

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.

  1. 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.

  1. 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

<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>
    <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.


In WPF RelativeSource binding exposes three properties to set:

1. Mode: This is an enum that could have four values:

a. PreviousData(value=0): It assigns the previous value of the property to the bound one

b. TemplatedParent(value=1): This is used when defining the templates of any control and want to bind to a value/Property of the control.

For example, define ControlTemplate:

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

c. Self(value=2): When we want to bind from a self or a property of self.

For example: Send checked state of checkbox as CommandParameter while setting the Command on CheckBox

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

d. FindAncestor(value=3): When want to bind from a parent control in Visual Tree.

For example: Bind a checkbox in records if a grid,if header checkbox is checked

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

2. AncestorType: when mode is FindAncestor then define what type of ancestor

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

3. AncestorLevel: when mode is FindAncestor then what level of ancestor (if there are two same type of parent in visual tree)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

Above are all use-cases for RelativeSource binding.

Here is a reference link.


In WPF RelativeSource binding exposes three properties to set:

1. Mode: This is an enum that could have four values:

a. PreviousData(value=0): It assigns the previous value of the property to the bound one

b. TemplatedParent(value=1): This is used when defining the templates of any control and want to bind to a value/Property of the control.

For example, define ControlTemplate:

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

c. Self(value=2): When we want to bind from a self or a property of self.

For example: Send checked state of checkbox as CommandParameter while setting the Command on CheckBox

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

d. FindAncestor(value=3): When want to bind from a parent control in Visual Tree.

For example: Bind a checkbox in records if a grid,if header checkbox is checked

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

2. AncestorType: when mode is FindAncestor then define what type of ancestor

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

3. AncestorLevel: when mode is FindAncestor then what level of ancestor (if there are two same type of parent in visual tree)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

Above are all use-cases for RelativeSource binding.

Here is a reference link.


In WPF RelativeSource binding exposes three properties to set:

1. Mode: This is an enum that could have four values:

a. PreviousData(value=0): It assigns the previous value of the property to the bound one

b. TemplatedParent(value=1): This is used when defining the templates of any control and want to bind to a value/Property of the control.

For example, define ControlTemplate:

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

c. Self(value=2): When we want to bind from a self or a property of self.

For example: Send checked state of checkbox as CommandParameter while setting the Command on CheckBox

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

d. FindAncestor(value=3): When want to bind from a parent control in Visual Tree.

For example: Bind a checkbox in records if a grid,if header checkbox is checked

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

2. AncestorType: when mode is FindAncestor then define what type of ancestor

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

3. AncestorLevel: when mode is FindAncestor then what level of ancestor (if there are two same type of parent in visual tree)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

Above are all use-cases for RelativeSource binding.

Here is a reference link.


In WPF RelativeSource binding exposes three properties to set:

1. Mode: This is an enum that could have four values:

a. PreviousData(value=0): It assigns the previous value of the property to the bound one

b. TemplatedParent(value=1): This is used when defining the templates of any control and want to bind to a value/Property of the control.

For example, define ControlTemplate:

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

c. Self(value=2): When we want to bind from a self or a property of self.

For example: Send checked state of checkbox as CommandParameter while setting the Command on CheckBox

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

d. FindAncestor(value=3): When want to bind from a parent control in Visual Tree.

For example: Bind a checkbox in records if a grid,if header checkbox is checked

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

2. AncestorType: when mode is FindAncestor then define what type of ancestor

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

3. AncestorLevel: when mode is FindAncestor then what level of ancestor (if there are two same type of parent in visual tree)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

Above are all use-cases for RelativeSource binding.

Here is a reference link.


Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

Don't forget TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

or

{Binding RelativeSource={RelativeSource TemplatedParent}}

I created a library to simplify the binding syntax of WPF including making it easier to use RelativeSource. Here are some examples. Before:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

After:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

Here is an example of how method binding is simplified. Before:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

After:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

You can find the library here: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

Note in the 'BEFORE' example that I use for method binding that code was already optimized by using RelayCommand which last I checked is not a native part of WPF. Without that the 'BEFORE' example would have been even longer.


I created a library to simplify the binding syntax of WPF including making it easier to use RelativeSource. Here are some examples. Before:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

After:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

Here is an example of how method binding is simplified. Before:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

After:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

You can find the library here: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

Note in the 'BEFORE' example that I use for method binding that code was already optimized by using RelayCommand which last I checked is not a native part of WPF. Without that the 'BEFORE' example would have been even longer.


It's worthy of note that for those stumbling across this thinking of Silverlight:

Silverlight offers a reduced subset only, of these commands


It's worthy of note that for those stumbling across this thinking of Silverlight:

Silverlight offers a reduced subset only, of these commands


I created a library to simplify the binding syntax of WPF including making it easier to use RelativeSource. Here are some examples. Before:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

After:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

Here is an example of how method binding is simplified. Before:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

After:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

You can find the library here: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

Note in the 'BEFORE' example that I use for method binding that code was already optimized by using RelayCommand which last I checked is not a native part of WPF. Without that the 'BEFORE' example would have been even longer.


I created a library to simplify the binding syntax of WPF including making it easier to use RelativeSource. Here are some examples. Before:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

After:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

Here is an example of how method binding is simplified. Before:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

After:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

You can find the library here: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

Note in the 'BEFORE' example that I use for method binding that code was already optimized by using RelayCommand which last I checked is not a native part of WPF. Without that the 'BEFORE' example would have been even longer.


It's worthy of note that for those stumbling across this thinking of Silverlight:

Silverlight offers a reduced subset only, of these commands


It's worthy of note that for those stumbling across this thinking of Silverlight:

Silverlight offers a reduced subset only, of these commands


Some useful bits and pieces:

Here's how to do it mostly in code:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

I largely copied this from Binding Relative Source in code Behind.

Also, the MSDN page is pretty good as far as examples go: RelativeSource Class


Some useful bits and pieces:

Here's how to do it mostly in code:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

I largely copied this from Binding Relative Source in code Behind.

Also, the MSDN page is pretty good as far as examples go: RelativeSource Class


Some useful bits and pieces:

Here's how to do it mostly in code:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

I largely copied this from Binding Relative Source in code Behind.

Also, the MSDN page is pretty good as far as examples go: RelativeSource Class


Some useful bits and pieces:

Here's how to do it mostly in code:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

I largely copied this from Binding Relative Source in code Behind.

Also, the MSDN page is pretty good as far as examples go: RelativeSource Class


I just posted another solution for accessing the DataContext of a parent element in Silverlight that works for me. It uses Binding ElementName.


I just posted another solution for accessing the DataContext of a parent element in Silverlight that works for me. It uses Binding ElementName.


I just posted another solution for accessing the DataContext of a parent element in Silverlight that works for me. It uses Binding ElementName.


I just posted another solution for accessing the DataContext of a parent element in Silverlight that works for me. It uses Binding ElementName.


I didn't read every answer, but I just want to add this information in case of relative source command binding of a button.

When you use a relative source with Mode=FindAncestor, the binding must be like:

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

If you don't add DataContext in your path, at execution time it can't retrieve the property.


I didn't read every answer, but I just want to add this information in case of relative source command binding of a button.

When you use a relative source with Mode=FindAncestor, the binding must be like:

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

If you don't add DataContext in your path, at execution time it can't retrieve the property.


I didn't read every answer, but I just want to add this information in case of relative source command binding of a button.

When you use a relative source with Mode=FindAncestor, the binding must be like:

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

If you don't add DataContext in your path, at execution time it can't retrieve the property.


I didn't read every answer, but I just want to add this information in case of relative source command binding of a button.

When you use a relative source with Mode=FindAncestor, the binding must be like:

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

If you don't add DataContext in your path, at execution time it can't retrieve the property.


This is an example of the use of this pattern that worked for me on empty datagrids.

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

This is an example of the use of this pattern that worked for me on empty datagrids.

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

This is an example of the use of this pattern that worked for me on empty datagrids.

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

This is an example of the use of this pattern that worked for me on empty datagrids.

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

If an element is not part of the visual tree, then RelativeSource will never work.

In this case, you need to try a different technique, pioneered by Thomas Levesque.

He has the solution on his blog under [WPF] How to bind to data when the DataContext is not inherited. And it works absolutely brilliantly!

In the unlikely event that his blog is down, Appendix A contains a mirror copy of his article.

Please do not comment here, please comment directly on his blog post.

Appendix A: Mirror of blog post

The DataContext property in WPF is extremely handy, because it is automatically inherited by all children of the element where you assign it; therefore you don’t need to set it again on each element you want to bind. However, in some cases the DataContext is not accessible: it happens for elements that are not part of the visual or logical tree. It can be very difficult then to bind a property on those elements…

Let’s illustrate with a simple example: we want to display a list of products in a DataGrid. In the grid, we want to be able to show or hide the Price column, based on the value of a ShowPrice property exposed by the ViewModel. The obvious approach is to bind the Visibility of the column to the ShowPrice property:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

Unfortunately, changing the value of ShowPrice has no effect, and the column is always visible… why? If we look at the Output window in Visual Studio, we notice the following line:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ShowPrice; DataItem=null; target element is ‘DataGridTextColumn’ (HashCode=32685253); target property is ‘Visibility’ (type ‘Visibility’)

The message is rather cryptic, but the meaning is actually quite simple: WPF doesn’t know which FrameworkElement to use to get the DataContext, because the column doesn’t belong to the visual or logical tree of the DataGrid.

We can try to tweak the binding to get the desired result, for instance by setting the RelativeSource to the DataGrid itself:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

Or we can add a CheckBox bound to ShowPrice, and try to bind the column visibility to the IsChecked property by specifying the element name:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

But none of these workarounds seems to work, we always get the same result…

At this point, it seems that the only viable approach would be to change the column visibility in code-behind, which we usually prefer to avoid when using the MVVM pattern… But I’m not going to give up so soon, at least not while there are other options to consider

The solution to our problem is actually quite simple, and takes advantage of the Freezable class. The primary purpose of this class is to define objects that have a modifiable and a read-only state, but the interesting feature in our case is that Freezable objects can inherit the DataContext even when they’re not in the visual or logical tree. I don’t know the exact mechanism that enables this behavior, but we’re going to take advantage of it to make our binding work…

The idea is to create a class (I called it BindingProxy for reasons that should become obvious very soon) that inherits Freezable and declares a Data dependency property:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable
 
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
 
    #endregion
 
    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

We can then declare an instance of this class in the resources of the DataGrid, and bind the Data property to the current DataContext:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

The last step is to specify this BindingProxy object (easily accessible with StaticResource) as the Source for the binding:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

Note that the binding path has been prefixed with “Data”, since the path is now relative to the BindingProxy object.

The binding now works correctly, and the column is properly shown or hidden based on the ShowPrice property.


If an element is not part of the visual tree, then RelativeSource will never work.

In this case, you need to try a different technique, pioneered by Thomas Levesque.

He has the solution on his blog under [WPF] How to bind to data when the DataContext is not inherited. And it works absolutely brilliantly!

In the unlikely event that his blog is down, Appendix A contains a mirror copy of his article.

Please do not comment here, please comment directly on his blog post.

Appendix A: Mirror of blog post

The DataContext property in WPF is extremely handy, because it is automatically inherited by all children of the element where you assign it; therefore you don’t need to set it again on each element you want to bind. However, in some cases the DataContext is not accessible: it happens for elements that are not part of the visual or logical tree. It can be very difficult then to bind a property on those elements…

Let’s illustrate with a simple example: we want to display a list of products in a DataGrid. In the grid, we want to be able to show or hide the Price column, based on the value of a ShowPrice property exposed by the ViewModel. The obvious approach is to bind the Visibility of the column to the ShowPrice property:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

Unfortunately, changing the value of ShowPrice has no effect, and the column is always visible… why? If we look at the Output window in Visual Studio, we notice the following line:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ShowPrice; DataItem=null; target element is ‘DataGridTextColumn’ (HashCode=32685253); target property is ‘Visibility’ (type ‘Visibility’)

The message is rather cryptic, but the meaning is actually quite simple: WPF doesn’t know which FrameworkElement to use to get the DataContext, because the column doesn’t belong to the visual or logical tree of the DataGrid.

We can try to tweak the binding to get the desired result, for instance by setting the RelativeSource to the DataGrid itself:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

Or we can add a CheckBox bound to ShowPrice, and try to bind the column visibility to the IsChecked property by specifying the element name:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

But none of these workarounds seems to work, we always get the same result…

At this point, it seems that the only viable approach would be to change the column visibility in code-behind, which we usually prefer to avoid when using the MVVM pattern… But I’m not going to give up so soon, at least not while there are other options to consider

The solution to our problem is actually quite simple, and takes advantage of the Freezable class. The primary purpose of this class is to define objects that have a modifiable and a read-only state, but the interesting feature in our case is that Freezable objects can inherit the DataContext even when they’re not in the visual or logical tree. I don’t know the exact mechanism that enables this behavior, but we’re going to take advantage of it to make our binding work…

The idea is to create a class (I called it BindingProxy for reasons that should become obvious very soon) that inherits Freezable and declares a Data dependency property:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable
 
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
 
    #endregion
 
    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

We can then declare an instance of this class in the resources of the DataGrid, and bind the Data property to the current DataContext:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

The last step is to specify this BindingProxy object (easily accessible with StaticResource) as the Source for the binding:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

Note that the binding path has been prefixed with “Data”, since the path is now relative to the BindingProxy object.

The binding now works correctly, and the column is properly shown or hidden based on the ShowPrice property.


If an element is not part of the visual tree, then RelativeSource will never work.

In this case, you need to try a different technique, pioneered by Thomas Levesque.

He has the solution on his blog under [WPF] How to bind to data when the DataContext is not inherited. And it works absolutely brilliantly!

In the unlikely event that his blog is down, Appendix A contains a mirror copy of his article.

Please do not comment here, please comment directly on his blog post.

Appendix A: Mirror of blog post

The DataContext property in WPF is extremely handy, because it is automatically inherited by all children of the element where you assign it; therefore you don’t need to set it again on each element you want to bind. However, in some cases the DataContext is not accessible: it happens for elements that are not part of the visual or logical tree. It can be very difficult then to bind a property on those elements…

Let’s illustrate with a simple example: we want to display a list of products in a DataGrid. In the grid, we want to be able to show or hide the Price column, based on the value of a ShowPrice property exposed by the ViewModel. The obvious approach is to bind the Visibility of the column to the ShowPrice property:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

Unfortunately, changing the value of ShowPrice has no effect, and the column is always visible… why? If we look at the Output window in Visual Studio, we notice the following line:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ShowPrice; DataItem=null; target element is ‘DataGridTextColumn’ (HashCode=32685253); target property is ‘Visibility’ (type ‘Visibility’)

The message is rather cryptic, but the meaning is actually quite simple: WPF doesn’t know which FrameworkElement to use to get the DataContext, because the column doesn’t belong to the visual or logical tree of the DataGrid.

We can try to tweak the binding to get the desired result, for instance by setting the RelativeSource to the DataGrid itself:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

Or we can add a CheckBox bound to ShowPrice, and try to bind the column visibility to the IsChecked property by specifying the element name:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

But none of these workarounds seems to work, we always get the same result…

At this point, it seems that the only viable approach would be to change the column visibility in code-behind, which we usually prefer to avoid when using the MVVM pattern… But I’m not going to give up so soon, at least not while there are other options to consider

The solution to our problem is actually quite simple, and takes advantage of the Freezable class. The primary purpose of this class is to define objects that have a modifiable and a read-only state, but the interesting feature in our case is that Freezable objects can inherit the DataContext even when they’re not in the visual or logical tree. I don’t know the exact mechanism that enables this behavior, but we’re going to take advantage of it to make our binding work…

The idea is to create a class (I called it BindingProxy for reasons that should become obvious very soon) that inherits Freezable and declares a Data dependency property:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable
 
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
 
    #endregion
 
    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

We can then declare an instance of this class in the resources of the DataGrid, and bind the Data property to the current DataContext:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

The last step is to specify this BindingProxy object (easily accessible with StaticResource) as the Source for the binding:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

Note that the binding path has been prefixed with “Data”, since the path is now relative to the BindingProxy object.

The binding now works correctly, and the column is properly shown or hidden based on the ShowPrice property.


If an element is not part of the visual tree, then RelativeSource will never work.

In this case, you need to try a different technique, pioneered by Thomas Levesque.

He has the solution on his blog under [WPF] How to bind to data when the DataContext is not inherited. And it works absolutely brilliantly!

In the unlikely event that his blog is down, Appendix A contains a mirror copy of his article.

Please do not comment here, please comment directly on his blog post.

Appendix A: Mirror of blog post

The DataContext property in WPF is extremely handy, because it is automatically inherited by all children of the element where you assign it; therefore you don’t need to set it again on each element you want to bind. However, in some cases the DataContext is not accessible: it happens for elements that are not part of the visual or logical tree. It can be very difficult then to bind a property on those elements…

Let’s illustrate with a simple example: we want to display a list of products in a DataGrid. In the grid, we want to be able to show or hide the Price column, based on the value of a ShowPrice property exposed by the ViewModel. The obvious approach is to bind the Visibility of the column to the ShowPrice property:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

Unfortunately, changing the value of ShowPrice has no effect, and the column is always visible… why? If we look at the Output window in Visual Studio, we notice the following line:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ShowPrice; DataItem=null; target element is ‘DataGridTextColumn’ (HashCode=32685253); target property is ‘Visibility’ (type ‘Visibility’)

The message is rather cryptic, but the meaning is actually quite simple: WPF doesn’t know which FrameworkElement to use to get the DataContext, because the column doesn’t belong to the visual or logical tree of the DataGrid.

We can try to tweak the binding to get the desired result, for instance by setting the RelativeSource to the DataGrid itself:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

Or we can add a CheckBox bound to ShowPrice, and try to bind the column visibility to the IsChecked property by specifying the element name:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

But none of these workarounds seems to work, we always get the same result…

At this point, it seems that the only viable approach would be to change the column visibility in code-behind, which we usually prefer to avoid when using the MVVM pattern… But I’m not going to give up so soon, at least not while there are other options to consider

The solution to our problem is actually quite simple, and takes advantage of the Freezable class. The primary purpose of this class is to define objects that have a modifiable and a read-only state, but the interesting feature in our case is that Freezable objects can inherit the DataContext even when they’re not in the visual or logical tree. I don’t know the exact mechanism that enables this behavior, but we’re going to take advantage of it to make our binding work…

The idea is to create a class (I called it BindingProxy for reasons that should become obvious very soon) that inherits Freezable and declares a Data dependency property:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable
 
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
 
    #endregion
 
    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
 
    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

We can then declare an instance of this class in the resources of the DataGrid, and bind the Data property to the current DataContext:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

The last step is to specify this BindingProxy object (easily accessible with StaticResource) as the Source for the binding:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

Note that the binding path has been prefixed with “Data”, since the path is now relative to the BindingProxy object.

The binding now works correctly, and the column is properly shown or hidden based on the ShowPrice property.


Questions with .net tag:

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface How to decode JWT Token? What's the difference between .NET Core, .NET Framework, and Xamarin? .NET Core vs Mono How to specify the port an ASP.NET Core application is hosted on? WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery Why is the Visual Studio 2015/2017/2019 Test Runner not discovering my xUnit v2 tests Build error, This project references NuGet IIS Config Error - This configuration section cannot be used at this path There is no argument given that corresponds to the required formal parameter - .NET Error Could not find a part of the path ... bin\roslyn\csc.exe Can you install and run apps built on the .NET framework on a Mac? What is the purpose of nameof? Microsoft.ReportViewer.Common Version=12.0.0.0 What is the default value for Guid? Authentication failed because remote party has closed the transport stream What is the difference between a Shared Project and a Class Library in Visual Studio 2015? How to break out of the IF statement No connection could be made because the target machine actively refused it 127.0.0.1 Default SecurityProtocol in .NET 4.5 How to properly make a http web GET request What is ".NET Core"? IOException: The process cannot access the file 'file path' because it is being used by another process System.web.mvc missing Disable SSL fallback and use only TLS for outbound connections in .NET? (Poodle mitigation) SQL Connection Error: System.Data.SqlClient.SqlException (0x80131904) Write to Windows Application Event Log Operator overloading ==, !=, Equals System.Net.WebException: The remote name could not be resolved: Running multiple async tasks and waiting for them all to complete What is an "index out of range" exception, and how do I fix it? Found conflicts between different versions of the same dependent assembly that could not be resolved Getting the first and last day of a month, using a given DateTime object Error 1053 the service did not respond to the start or control request in a timely fashion BadImageFormatException. This will occur when running in 64 bit mode with the 32 bit Oracle client components installed Download files from SFTP with SSH.NET library An object reference is required to access a non-static member AppendChild() is not a function javascript Send JSON via POST in C# and Receive the JSON returned? Why is HttpClient BaseAddress not working? KERNELBASE.dll Exception 0xe0434352 offset 0x000000000000a49d

Questions with wpf tag:

Error: the entity type requires a primary key Reportviewer tool missing in visual studio 2017 RC Pass command parameter to method in ViewModel in WPF? Calling async method on button click Setting DataContext in XAML in WPF How to resolve this System.IO.FileNotFoundException System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll? Binding an Image in WPF MVVM How to bind DataTable to Datagrid Setting cursor at the end of any text of a textbox Change color of Button when Mouse is over Binding ComboBox SelectedItem using MVVM Implement Validation for WPF TextBoxes How to make all controls resize accordingly proportionally when window is maximized? Use StringFormat to add a string to a WPF XAML binding WPF Datagrid Get Selected Cell Value What's the difference between the Window.Loaded and Window.ContentRendered events How to format number of decimal places in wpf using style/template? Options for embedding Chromium instead of IE WebBrowser control with WPF/C# How to set DataGrid's row Background, based on a property value using data bindings WPF C# button style Add an image in a WPF button How do you change Background for a Button MouseOver in WPF? What event handler to use for ComboBox Item Selected (Selected Item not necessarily changed) How to change TextBox's Background color? Wpf DataGrid Add new row How to clear a textbox once a button is clicked in WPF? Close Window from ViewModel Add Items to Columns in a WPF ListView WPF Check box: Check changed handling An error occurred while updating the entries. See the inner exception for details Binding ConverterParameter WPF Label Foreground Color The name does not exist in the namespace error in XAML Making WPF applications look Metro-styled, even in Windows 7? (Window Chrome / Theming / Theme) How to add a vertical Separator? WPF Binding to parent DataContext How to bind WPF button to a command in ViewModelBase? What is the difference between WCF and WPF? Window vs Page vs UserControl for WPF navigation? 'System.Reflection.TargetInvocationException' occurred in PresentationFramework.dll How to load image to WPF in runtime? Add items to comboBox in WPF Adding placeholder text to textbox Accessing UI (Main) Thread safely in WPF How do I create a timer in WPF? WPF popup window How to refresh datagrid in WPF How do I open a second window from the first window in WPF? Find Item in ObservableCollection without using a loop

Questions with xaml tag:

Setting DataContext in XAML in WPF Change color of Button when Mouse is over Implement Validation for WPF TextBoxes Use StringFormat to add a string to a WPF XAML binding How to format number of decimal places in wpf using style/template? How to set DataGrid's row Background, based on a property value using data bindings WPF C# button style How to clear a textbox once a button is clicked in WPF? Add Items to Columns in a WPF ListView Binding ConverterParameter The name does not exist in the namespace error in XAML How to add a vertical Separator? Example using Hyperlink in WPF How can I style the border and title bar of a window in WPF? Create a menu Bar in WPF? Properties order in Margin How to add comments into a Xaml file in WPF? How to set a binding in Code? How do I make a WPF TextBlock show my text on multiple lines? Binding a Button's visibility to a bool value in ViewModel How to add a ScrollBar to a Stackpanel How to bind an enum to a combobox control in WPF? Datagrid binding in WPF Format Date/Time in XAML in Silverlight Change DataGrid cell colour based on values How to make overlay control above all other controls? WPF button click in C# code WPF Binding StringFormat Short Date String How do I make XAML DataGridColumns fill the entire DataGrid? Difference between SelectedItem, SelectedValue and SelectedValuePath How do I set a ViewModel on a window in XAML using DataContext property? WPF MVVM: How to close a window Handling the window closing event with WPF / MVVM Light Toolkit Access parent DataContext from DataTemplate Adding a Button to a WPF DataGrid WPF: Create a dialog / prompt How to set MouseOver event/trigger for border in XAML? The calling thread must be STA, because many UI components require this Simple (I think) Horizontal Line in WPF? Accessing a resource via codebehind in WPF How can I bind a background color in WPF/XAML? How to get the size of the current screen in WPF? WPF - add static items to a combo box WPF TabItem Header Styling WPF Application that only has a tray icon Set focus on TextBox in WPF from view model How do I get a TextBox to only accept numeric input in WPF? How can I set the color of a selected row in DataGrid How can I make a TextBox be a "password box" and display stars when using MVVM? Setting a property with an EventTrigger

Questions with data-binding tag:

Angular 2 Checkbox Two Way Data Binding Get user input from textarea Launch an event when checking a checkbox in Angular2 Angular 2 two way binding using ngModel is not working Binding ComboBox SelectedItem using MVVM Implement Validation for WPF TextBoxes Use StringFormat to add a string to a WPF XAML binding how to bind datatable to datagridview in c# How to format number of decimal places in wpf using style/template? AngularJS - Binding radio buttons to models with boolean values How to Implement DOM Data Binding in JavaScript How to clear exisiting dropdownlist items when its content changes? AngularJS : The correct way of binding to a service properties What is two way binding? Ng-model does not update controller value Fill Combobox from database AngularJS : ng-model binding not updating when changed with jQuery How does data binding work in AngularJS? How can I data bind a list of strings to a ListBox in WPF/WP7? How to set a binding in Code? ORA-01008: not all variables bound. They are bound Binding a Button's visibility to a bool value in ViewModel How to set selected value from Combobox? How to bind an enum to a combobox control in WPF? How to force a WPF binding to refresh? How do I bind a List<CustomObject> to a WPF DataGrid? How to hide a TemplateField column in a GridView Binding a list in @RequestParam Jackson with JSON: Unrecognized field, not marked as ignorable How to format DateTime columns in DataGridView? Access parent DataContext from DataTemplate ComboBox SelectedItem vs SelectedValue How to bind multiple values to a single WPF TextBlock? WPF: simple TextBox data binding Data binding for TextBox WPF Databinding: How do I access the "parent" data context? Binding to static property WPF checkbox binding How to bind a List to a ComboBox? Binding a WPF ComboBox to a custom list How to bind RadioButtons to an enum? Richtextbox wpf binding How do I bind a WPF DataGrid to a variable number of columns? ListBox vs. ListView - how to choose for data binding How do I use WPF bindings with RelativeSource? WPF Data Binding and Validation Rules Best Practices

Questions with relativesource tag:

Access parent DataContext from DataTemplate WPF TemplateBinding vs RelativeSource TemplatedParent How do I use WPF bindings with RelativeSource?