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

The ninety-second part of the Windows Presentation Foundation Fundamentals tutorial continues to look at data binding. This instalment considers the DataContext property of WPF controls, which allows binding to any object.

Data Binding

In previous articles we've started to investigate data binding. To demonstrate, we've linked the properties of controls together. This meant that changing the property of one control automatically updated another to match. In this article we are going to look at a more powerful form of binding, which permits you to bind your WPF controls to the properties of any object. This is using the DataContext property.

DataContext is a property that is defined within FrameworkElement, so is available to all of the WPF controls that we've considered in this tutorial. Its data type is System.Object, so you can set the property to an object of any type. Once set, you can refer to the object's properties in the Path of your bindings without specifying a Source; the data context is the default source for bindings.

The data context for a control is inherited by its children, unless you specify another DataContext value for those controls. This means that you do not necessarily need to set the DataContext property for every item in a window. You can set the property of a common ancestor to use the same binding source over multiple controls.

Let's demonstrate with a new solution. Create a new WPF application project in Visual Studio named, "DataContextDemo". Once the project is prepared, replace the XAML in the main window with the following:

<Window x:Class="DataContextDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Personal Details"
        Height="180"
        Width="250"
        ResizeMode="NoResize">
    <Grid Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBlock>First Name</TextBlock>
        <TextBox Grid.Column="1" Margin="5 0 0 5"/>

        <TextBlock Grid.Row="1">Last Name</TextBlock>
        <TextBox Grid.Column="1" Grid.Row="1" Margin="5 0 0 5"/>

        <TextBlock Grid.Row="2">Age</TextBlock>
        <StackPanel Grid.Column="1" Grid.Row="2" Margin="5 0 0 5">
            <Slider Minimum="16" Maximum="120" />
            <TextBlock Text="16" HorizontalAlignment="Center"/>
        </StackPanel>

        <Button Grid.Column="1" Grid.Row="3" HorizontalAlignment="Right">New Window</Button>
    </Grid>
</Window>

The above XAML produces the following window design:

WPF DataContext Data Binding Example Window

The window allows a user to enter some personal details. You can imagine that the provided information would be held in a single, "PersonalDetails", object. Systems without data binding may force you to manually copy information from such a data object into the controls, then copy any updates back to the object. With WPF we can perform these updates automatically using data binding.

Creating the Data Class

Before we can bind the window we need a class that defines the required properties. Add a new class named, "PersonalDetails". Replace the code for the class with the following:

public class PersonalDetails
{
    string _firstName = "Bob";
    string _lastName = "Smith";
    int _age = 25;
    static PersonalDetails _details;

    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }

    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; }
    }

    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }
     
    public static PersonalDetails GetDetails()
    {
        if (_details == null)
            _details = new PersonalDetails();

        return _details;
    }
}

The class defines properties for a name and age. You can see that it uses the Singleton design pattern. This ensures that only one PersonalDetails instance ever exists. We'll use this behaviour later in the example code.

31 August 2014