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 - Data Templates

The one hundred and third part of the Windows Presentation Foundation Fundamentals tutorial continues to investigate data binding. The topic of this article is the use of data templates with items controls, to control the display of items in a list.

Data Templates

In the previous instalment of the WPF tutorial we looked at the ItemsSource property of the ItemsControl class and how it allows you to bind controls to a sequence of values. We also saw the ObservableCollection class. This specialised, generic collection holds a sequence of items, to which controls can be bound. It also provides automatic notifications, which WPF uses to update the user interface if the collection changes.

In the examples in the earlier article we bound a ListBox to a collection of strings. Each item in the ListBox displayed one of those strings. It is common to wish to bind to a collection that contains values or objects of other data types. You can use the properties of ItemsControl to select a member to display as the text. However, often you will want to combine properties from the source objects or include richer user interface elements, such as styled text, input controls or images. This is all possible using data templates.

When you apply a data template to an items control, you specify a control that should be used instead of text for each item in the source data. The control can be a layout control with many children. The template is repeated for each item in the collection, with the appropriate object becoming the template's data context. You can include standard data binding expressions within the template to generate the final user interface.

Example Code

To demonstrate, we need a sample project. We'll create a program that shows a list of contact details and permits new items to be added to the list. Each item will include a name, a telephone number and an email address. Using a data template, we'll be able to show all three properties for each item in the list.

Contact Details Class

To begin, create a new WPF application in Visual Studio named, "DataTemplateDemo". We'll create the class that holds a person's contact details first. Add a file named, "ContactDetails" with the following code:

using System.ComponentModel;

namespace DataTemplateDemo
{
    public class ContactDetails : INotifyPropertyChanged
    {
        string _name;
        string _telephone;
        string _email;

        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnNotifyPropertyChanged("Name");
            }
        }

        public string Telephone
        {
            get { return _telephone; }
            set
            {
                _telephone = value;
                OnNotifyPropertyChanged("Telephone");
            }
        }

        public string Email
        {
            get { return _email; }
            set
            {
                _email = value;
                OnNotifyPropertyChanged("Email");
            }
        }

        private void OnNotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

Data Context Class

Next we'll create a class that holds all of the data and functionality required for the window's bindings. We'll use this as the window's data context. The class includes an observable collection of ContactDetails objects for the main list. It also includes a single ContactDetails instance, which will be editable. Finally, we'll include a method that adds the editable contact to the list before creating a new object for editing.

Add a class file named, "ContactList", with the following code:

using System.Collections.ObjectModel;
using System.ComponentModel;

namespace DataTemplateDemo
{
    public class ContactList : INotifyPropertyChanged
    {
        ContactDetails _editableContact;

        public ContactList()
        {
            Contacts = new ObservableCollection<ContactDetails>();
            EditableContact = new ContactDetails();
       }

        public ObservableCollection<ContactDetails> Contacts { get; set; }

        public ContactDetails EditableContact
        {
            get { return _editableContact; }
            set
            {
                _editableContact = value;
                OnNotifyPropertyChanged("EditableContact");
            }
        }

        private void OnNotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void AddEditableContact()
        {
            Contacts.Add(EditableContact);
            EditableContact = new ContactDetails();
        }
    }
}
11 October 2014