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 - Asynchronous Bindings

The ninety-ninth part of the Windows Presentation Foundation Fundamentals tutorial continues the introduction to data binding. This article demonstrates the use of asynchronous bindings, which allow the user interface to become responsive more quickly.

Data Binding

In recent articles in this series we've examined data binding. So far, every binding that we have created has been synchronous. In each of the examples that we've seen, a window loads and shows controls with values that are bound to properties of other controls or to those of the control's data context. Each property is read on loading and the window does not permit user interaction until all of the bindings are complete.

Synchronous bindings are usually acceptable. In general, properties of controls and classes should provide their values quickly, so the delay between starting the binding process and returning control to the user should be minimal. However, sometimes it is not possible to load the values quickly enough. For example, information may be retrieved from a slow service or web site. In these cases, the user experience is impacted by an unresponsive window. If the delay is long enough, the user may assume that the program has crashed or become unstable.

One solution to the problem of slow data bound properties is to use asynchronous data binding. With asynchronous bindings the source is read using a background thread, allowing the user interface thread to continue executing so that your application remains responsive.

To demonstrate, let's create a sample application that includes slow, synchronous bindings. We'll then switch to asynchronous data binding to see the benefits. Start by creating a new WPF application solution in Visual Studio. Name the new solution, "AsyncBindingDemo". Once the project is prepared, replace the XAML for the main window with the following:

<Window x:Class="AsyncBindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Asychronous Binding Demo" Height="100" Width="250"
        Foreground="Blue"
        Loaded="Window_Loaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="75"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBlock Foreground="Black">First Name</TextBlock>
        <TextBlock Grid.Column="1" Text="{Binding FirstName}" />

        <TextBlock Foreground="Black" Grid.Row="1">Last Name</TextBlock>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LastName}" />
    </Grid>
</Window>

The XAML defines a window with two data bound TextBlocks. These will show the first and last names of a person. We now need a class to hold the data. Create a new class file named, "Person" and add the following using directive. We will use the System.Threading namespace when mimicking slow operations.

using System.Threading;

Complete the class using the code below. Note the use of the Thread.Sleep method to introduce an artificial delay to the properties.

public class Person
{
    public string FirstName
    {
        get
        {
            Thread.Sleep(5000);
            return "Bob";
        }
    }

    public string LastName
    {
        get
        {
            Thread.Sleep(5000);
            return "Smith";
        }
    }
}

To complete the program, open the code behind the main window. We'll set the DataContext to a new Person object in the Loaded event. Add the following code to the class:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    DataContext = new Person();
}

Run the program to see the results. After a short delay, the window should appear as shown below. During the delay, the window is responsive because the UI thread is busy reading the property values.

WPF Asynchronous Binding Demo window

Asynchronous Bindings

Making a data binding asynchronous is as simple as setting its IsAsync property to true. WPF takes care of spawning threads and updating the user interface automatically. To demonstrate, replace the XAML of the four TextBlocks with the following code. This switches the two data bindings to be asynchronous.

<TextBlock Foreground="Black">First Name</TextBlock>
<TextBlock Grid.Column="1" Text="{Binding FirstName,IsAsync=True}" />

<TextBlock Foreground="Black" Grid.Row="1">Last Name</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LastName,IsAsync=True}" />

Run the program again to see the results. The window appears and becomes responsive before the bindings complete. Initially the bound text is blank whilst the properties are read in the background. When the properties return values, the text blocks update.

If you don't want the controls to show the default values whilst the asynchronous binding is in progress, you can set the FallbackValue. This will be shown until the bindings complete successfully.

To demonstrate, let's set the fallback values to "Loading...":

<TextBlock Foreground="Black">First Name</TextBlock>
<TextBlock Grid.Column="1" Text="{Binding FirstName,IsAsync=True,
                                          FallbackValue=Loading...}" />

<TextBlock Foreground="Black" Grid.Row="1">Last Name</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LastName,IsAsync=True,
                                                       FallbackValue=Loading...}" />

Run the program for a final time. You'll see the "Loading..." text appear at a similar time to the window becoming fully responsive to user interactions. A few seconds later, the property values are populated.

27 September 2014