BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Windows Presentation Foundation
.NET 4.0+

WPF Data Binding - Relative Sources

The ninety-first part of the Windows Presentation Foundation Fundamentals tutorial continues the examination of data binding. This article expands upon binding controls to each other by using relative, rather than explicit, source controls.

Ancestor Binding

The second type of relative data binding allows you to link a control to information from one of its ancestors in the logical tree. In the basic form, you specify the type of the control to which you wish to bind. WPF moves upwards through the logical tree until a matching control is found. The Path is then used to determine the property to use as the data source.

To perform ancestor binding, you can use a RelativeSource object with its Mode set to the FindAncestor value from the RelativeSourceMode enumeration. The AncestorType property should be set to the type of the control to use as the source. In XAML, you can use a partial expression such as:

RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}}

The above specifies that the first Window that can be found above the target control within the logical tree will be the source of the binding. Let's use this to bind the second yellow TextBlock so that it shows the window's title. Modify the code for the control as follows:

<TextBlock Background="Yellow"
            Text="{Binding RelativeSource={RelativeSource FindAncestor,
                   AncestorType={x:Type Window}},Path=ActualWidth}"/>

Run the program to see the results. You should see the window's title in the TextBlock.

Skipping Ancestors

Sometimes you will not want to bind to the closest ancestor of the specified type. You might wish to skip one or more controls of that type, searching higher in the logical tree for another control. To do this, set the AncestorLevel property of the RelativeSource. The default value of one finds the closest matching control. A value of two finds the second closest, and so on.

We can demonstrate the ancestor level options using the TextBlocks in the second GroupBox. Let's bind the first yellow TextBlock in this group so that it shows the header of the GroupBox closest to it in the logical tree. We'll bind the second yellow TextBlock to a GroupBox header but set the AncestorLevel to two so that the outer group is used.

Change the XAML for the second GroupBox and its contents as follows. Note the AncestorLevel value used in the final text block.

<GroupBox Header="Inner Group 2">
    <StackPanel>
        <TextBlock>This Header:</TextBlock>
        <TextBlock Background="Yellow"
                   Text="{Binding RelativeSource={RelativeSource FindAncestor,
                          AncestorType={x:Type GroupBox}},Path=Header}"/>
        <TextBlock Margin="0 5 0 0">Parent Header:</TextBlock>
        <TextBlock Background="Yellow"
                   Text="{Binding RelativeSource={RelativeSource FindAncestor,
                          AncestorType={x:Type GroupBox},AncestorLevel=2},Path=Header}"/>
    </StackPanel>
</GroupBox>

Run the program for a final time to see the results. You should see the inner and outer group box names in the yellow areas.

26 August 2014