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.

Data Binding

In previous articles we've started to look at data binding. This powerful WPF feature allows you to link a control's properties to a data source without repetitive plumbing code. As the data source changes, the control updates accordingly and changes made by the user can be reflected in the source data.

In the previous article we saw how the properties of two controls can be bound together so that they remain synchronised as the values are changed. We applied names to the source controls and used those names explicitly in the data binding expressions.

In this article we'll look further at binding controls to each other. However, rather than using control names, we'll use relative sources. This allows you to link properties within a single control or between a control and its parents, without using names. This is important where naming is not possible. For example, when using data bindings within reusable styles or templates.

To demonstrate we need a sample solution. Create a new WPF application project in Visual Studio with the name, "RelativeBindingDemo". Once loaded, replace the XAML of the main window with the following:

<Window x:Class="RelativeBindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RelativeSource Binding Demo"
        MinHeight="250"
        Height="250"
        Width="250">
    <GroupBox Header="Outer Group">
        <UniformGrid Columns="1">
            <GroupBox Header="Inner Group 1">
                <StackPanel>
                    <TextBlock>Text Width:</TextBlock>
                    <TextBlock Background="Yellow"/>
                    <TextBlock Margin="0 5 0 0">Window Width:</TextBlock>
                    <TextBlock Background="Yellow"/>
                </StackPanel>
            </GroupBox>

            <GroupBox Header="Inner Group 2">
                <StackPanel>
                    <TextBlock>This Header:</TextBlock>
                    <TextBlock Background="Yellow"/>
                    <TextBlock Margin="0 5 0 0">Parent Header:</TextBlock>
                    <TextBlock Background="Yellow"/>
                </StackPanel>
            </GroupBox>
        </UniformGrid>
    </GroupBox>
</Window>

The XAML describes a window containing a GroupBox. Within the GroupBox are two further GroupBoxes, each containing a set of TextBlocks. We'll use data binding to populate the properties of the TextBlocks that have yellow backgrounds.

WPF RelativeSource Binding Example Window

Self Binding

We'll look at two forms of relative data binding in this article. There are others, which we will see later in the tutorial. The first of the two is self binding. This is where a one property of a control is bound to another property of the same control. This keeps the two properties synchronised automatically.

When performing self binding, the Path for the binding expression works in the same manner as when using a named control. Only the source of the binding is changed. To achieve relative binding, the RelativeSource property of the binding is set to a RelativeSource object. For a self binding, you create the RelativeSource object using the class's static Self property. In XAML, the relative source is set in the binding expression as follows:

RelativeSource={RelativeSource Self}

To demonstrate, let's bind the first yellow TextBlock's Text property so that it shows the width of the control. Modify this TextBlock's XAML as follows:

<TextBlock Background="Yellow"
           Text="{Binding RelativeSource={RelativeSource Self},Path=ActualWidth}"/>

You can see that the binding includes a reference to the relative source and a Path that identifies the source property as the ActualWidth value. Run the program and try resizing the window. You should see that the TextBlock continues to show its own width.

26 August 2014