Data Binding

.Data Binding

"The generic ObservableCollection class is a good collection choice for data binding, because it implements the INotifyPropertyChanged and INotifyCollectionChanged interfaces."

A data binding allows data to flow between the user interface and data objects. A data binding consists of a target and a source. The target is usually a property of a control, and the source is usually a property of a data object.

  • Bound data can flow in one of three modes:
    1. OneTime - the target of the bind operation will update with the source only when it is created

    2. OneWay - the target of the bind operation will update with the source every time the source changes. This is the default binding mode.

    3. TwoWay- the bind operation will update both the source and the target when either of them changes. This mode is used when you want to get data from the user.
  • Self-binding refers to a state where an element binds to the DataContext property. This is accomplished by setting the controls data source property to "{Binding}". For example, a self-binding TextBox control would set property Text="{Binding}" on the control. See example below: "Binding Control to a Single Item".

  • The source of the binding must implement the INotifiedPropertyChanged interface for automatic updates to occur. This interface contains the PropertyChanged event, which tells the binding the data has changed.


Data Context

  • DataContext allows for the definition of a common source for all the UI binding in XAML at a certain level (page level, element level).

  • The DataContext can be set at either the page level or the element level.
,Data Binding


Data Binding

Binding Control to a Single Item

This an example of binding a control to a single item.

Target: Text property of text box.
Source: Pet object.

MainPage.xaml

<UserControl x:Class="databinding1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot"
          Background="#FF0000FF">
        <TextBox x:Name="textBox1"
                 Text="{Binding}"
                 FontSize="12"
                 Height="100"
                 Width="400"
                 IsReadOnly="True"
                 TextWrapping="Wrap"
                 AcceptsReturn="True" />
    </Grid>
</UserControl>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace databinding1
{
    public partial class MainPage : UserControl
    {

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context to a new Pet.
            textBox1.DataContext = new Pet("Dog", "Holly", new DateTime(2001, 5, 1));
        }

        // Pet object
        public class Pet
        {
            public Pet() { }

            public Pet(string petType, string petName, DateTime birthDate)
            {
                PetName = petName;
                PetType = petType;
                BirthDate = birthDate;
            }

            public string PetName { get; set; }
            public string PetType { get; set; }
            public DateTime BirthDate { get; set; }

            // Override the ToString method.
            public override string ToString()
            {
                return PetType + " is called " + PetName +                      
                    " and was born on " + BirthDate.ToString("d") + ".";
            }
        }
    }
}

.Output from Binding Control to a Single Item


Binding Control to a Single Item

Binding a Control to a Collection of Objects

The generic ObservableCollection class is a good collection choice for data binding, because it implements the INotifyPropertyChanged and INotifyCollectionChanged interfaces. These interfaces provide change notification to bound controls when an item in the list changes or a property of the list itself changes. If you want your bound controls to update with changes to properties of objects in the collection, the business object should also implement INotifyPropertyChanged.

This an example of binding a control to an observable collection of objects.

Target: DataContext of ComboBox.
Source: Observable Collection of Pet objects.

MainPage.xaml

<UserControl x:Class="databinding1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="ContentPanel"
          Grid.Row="1"
          Margin="12,0,12,0">
        <ComboBox x:Name="ComboBox1"
                  ItemsSource="{Binding}"
                  Foreground="Black"
                  FontSize="12"
                  Height="40"
                  Width="480" />
    </Grid>

</UserControl>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace databinding1
{
    public partial class MainPage : UserControl
    {
        public ObservableCollection<Pet> MyPets = new ObservableCollection<Pet>();

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context to a new Pet.
            //textBox1.DataContext = new Pet("Dog", "Holly", new DateTime(2001, 5, 1));

            // Add items to the collection.
            MyPets.Add(new Pet("Dog", "Holly", new DateTime(2001, 5, 1)));
            MyPets.Add(new Pet("Cat", "Shadow", new DateTime(2000, 11, 1)));
            MyPets.Add(new Pet("Cat", "Tessa", new DateTime(2007, 2, 1)));           

            // Set the data context for the combo box.
            ComboBox1.DataContext = MyPets;
        }

        // Pet object
        public class Pet
        {
            public Pet() { }

            public Pet(string petType, string petName, DateTime birthDate)
            {
                PetName = petName;
                PetType = petType;
                BirthDate = birthDate;
            }

            public string PetName { get; set; }
            public string PetType { get; set; }
            public DateTime BirthDate { get; set; }

            // Override the ToString method.
            public override string ToString()
            {
                return PetType + " is called " + PetName +
                    " and was born on " + BirthDate.ToString("d") + ".";
            }
        }
    }
}

.Binding a Control to a Collection of Objects


Binding a Control to a Collection of Objects


Displaying Items in a Control with a Data Template

You can display items in a list by using the item's ToString method. However, a more common scenario is to provide a customized display of data bound items by using a DataTemplate. A DataTemplate enables you to customize how list items are displayed in a control. Typically, you set the data template by using the ContentTemplate property of a content control or the ItemTemplate property of an items control.

This an example of formatting the data displayed in the above example with a data template.

Target: DataContext of ComboBox.
Source: Observable Collection of Pet objects.

MainPage.xaml

<UserControl x:Class="databinding1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="ContentPanel"
          Grid.Row="1"
          Margin="12,0,12,0">
        <ComboBox x:Name="ComboBox1"
                  ItemsSource="{Binding}"
                  Foreground="Black"
                  FontSize="12"
                  Height="40"
                  Width="480" >

            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding PetType}"
                                   FontWeight="Bold"
                                   FontSize="12" />
                        <TextBlock Text="{Binding PetName}"
                                   FontStyle="Italic"
                                   FontSize="12" />
                        <TextBlock Text="{Binding BirthDate}"
                                   FontSize="12" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </Grid>

</UserControl>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace databinding1
{
    public partial class MainPage : UserControl
    {
        public ObservableCollection<Pet> MyPets = new ObservableCollection<Pet>();

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context to a new Pet.
            //textBox1.DataContext = new Pet("Dog", "Holly", new DateTime(2001, 5, 1));

            // Add items to the collection.
            MyPets.Add(new Pet("Dog", "Holly", new DateTime(2001, 5, 1)));
            MyPets.Add(new Pet("Cat", "Shadow", new DateTime(2000, 11, 1)));
            MyPets.Add(new Pet("Cat", "Tessa", new DateTime(2007, 2, 1)));           

            // Set the data context for the combo box.
            ComboBox1.DataContext = MyPets;
        }

        // Pet object
        public class Pet
        {
            public Pet() { }

            public Pet(string petType, string petName, DateTime birthDate)
            {
                PetName = petName;
                PetType = petType;
                BirthDate = birthDate;
            }

            public string PetName { get; set; }
            public string PetType { get; set; }
            public DateTime BirthDate { get; set; }

            // Override the ToString method.
            public override string ToString()
            {
                return PetType + " is called " + PetName +
                    " and was born on " + BirthDate.ToString("d") + ".";
            }
        }
    }
}

.Displaying Items in a Control with a Data Template


Displaying Items in a Control with a Data Template


Adding a Details View

To display the details of an item when it is selected from a collection, you have to create the appropriate UI and bind the UI to the data that you want it to display. Additionally, you must use a CollectionViewSource as the data context to enable the details view to bind to the current item. In the example below, the data context of the entire page or user control is set to the collection view source, and the combo box and details view inherit the data context. This enables the combo box to bind to the collection and display the same list of items while the details view automatically binds to the current item. The details view does not need to explicitly bind to the current item because the collection view source automatically provides the appropriate level of data.

This an example expands upon the previous examples by adding a details view.

Target: DataContext of ComboBox.
Source: CollectionViewSource (Observable Collection of Pet objects).

MainPage.xaml

<UserControl x:Class="databinding1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="ContentPanel"
          Grid.Row="1"
          Margin="12,0,12,0">

        <StackPanel Width="750"
                    Height="200"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center">

            <ComboBox x:Name="ComboBox1"
                  ItemsSource="{Binding}"
                  Foreground="Black"
                  FontSize="12"
                  Height="40"
                  Width="480" >

            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal"
                                Margin="2">
                        <TextBlock Text="Pet Type:"
                                   Margin="2" />
                        <TextBlock Text="{Binding PetType}"
                                   Margin="2" />
                        <TextBlock Text="Pet Name:"
                                   Margin="10,2,0,2" />
                        <TextBlock Text="{Binding PetName}"
                                   Margin="2" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
            </ComboBox>

            <!--The UI for the details view-->
            <StackPanel x:Name="PetDetails">
                <TextBlock Text="{Binding PetType}"
                           FontWeight="Bold"
                           FontSize="12" />
                <TextBlock Text="{Binding PetName}"
                           FontStyle="Italic"
                           FontSize="12" />
                <TextBlock Text="{Binding BirthDate}"
                           FontSize="12" />
            </StackPanel>
        </StackPanel>
    </Grid>

</UserControl>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Windows.Data;

namespace databinding1
{
    public partial class MainPage : UserControl
    {
        public ObservableCollection<Pet> MyPets = new ObservableCollection<Pet>();

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context to a new Pet.
            //textBox1.DataContext = new Pet("Dog", "Holly", new DateTime(2001, 5, 1));

            // Add items to the collection.
            MyPets.Add(new Pet("Dog", "Holly", new DateTime(2001, 5, 1)));
            MyPets.Add(new Pet("Cat", "Shadow", new DateTime(2000, 11, 1)));
            MyPets.Add(new Pet("Cat", "Tessa", new DateTime(2007, 2, 1)));           

            // Set the data context for the combo box.
//            ComboBox1.DataContext = MyPets;

            // Set the DataContext on the parent object instead of the ComboBox
            // so that both the ComboBox and details view can inherit it. 
            // ComboBox1.DataContext = MyMusic;
            this.DataContext = new CollectionViewSource { Source = MyPets };
        }

        // Pet object
        public class Pet
        {
            public Pet() { }

            public Pet(string petType, string petName, DateTime birthDate)
            {
                PetName = petName;
                PetType = petType;
                BirthDate = birthDate;
            }

            public string PetName { get; set; }
            public string PetType { get; set; }
            public DateTime BirthDate { get; set; }

            // Override the ToString method.
            public override string ToString()
            {
                return PetType + " is called " + PetName +
                    " and was born on " + BirthDate.ToString("d") + ".";
            }
        }
    }
}

.Adding a Details View


A Details View



Reference Articles


Top