Click here to Skip to main content
Click here to Skip to main content

Databinding in Silverlight applications

, 11 May 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
In this article, you will learn the basic concepts of simple data binding in a Silverlight application.

Table of Contents

Overview

In this article, you will learn the basic concepts of simple data binding in a Silverlight application. I have covered the different types of binding modes available and how to use them declaratively and programmatically. We will also see how to do binding for a collection, the importance of the INotifyPropertyChanged interface method, and the ObservableCollection class. Our ultimate goal is to fetch information from a back-end or from a .NET object and show it in the user interface.

These are some of my other articles on Silverlight technology:

Introduction to Databinding

Databinding is the process of establishing a connection between a source and target. In Silverlight databinding, the source is the CRL object and the target is Silverlight controls (XAML Elements). Let me show you a visual.

Binding Modes

There are three types of data binding that happens in Silverlight applications between a source and target.

  1. OneTime data binding
  2. OneWay data binding (default mode)
  3. TwoWay data binding

OneTime data binding: As the name suggests, data binding happens between the source and target only once. In this binding, the source (CRL object) data will bind with the target (XAML element) only when the page executes the first time. Later on, any changes made in the source will not be reflected back in the target element. You will prefer to use this binding mode to reduce overhead if you know that the source property won’t change.

OneWay data binding: In this data binding, the source will immediately inform about changes to the target control. We will be using this binding only for frequently changed elements. This is the default mode.

TwoWay data binding: This happens in bidirectional mode. Whenever any change occurs in the backend or the CRL object, it will inform to the XAML controls immediately, and vice versa.

Binding in Silverlight requires three things:

  1. The first thing we need is target UI element’s property. This can be a TextBox control's Text property or ListBox control’s ItemsSource property etc… You can call this the DependencyProperty of a FrameworkElement.
  2. The source object that contains the data that flows between the source and the target. The source can be any CLR object.
  3. A binding object to handle the communication between these two.

To implement data binding in XAML code, you need to implement a binding statement. Here is the syntax for how to use a binding statement in XAML:

The binding is created in XAML using the {Binding ...} syntax.

<TextBox x:Name="tbFirstName" Text="{Binding Path=FirstName, Mode=OneTime}" 
         Grid.Column="2" Grid.Row="1"></TextBox>

The binding statement has many properties, but here is a list of frequently used properties of the Binding statement:

  • Path is the name of the source property to get the data from.
  • Mode is the connection type (OneTime, OneWay, and TwoWay) between the source and the target.
  • Source is the standard CLR object that contains the data.
  • Converter is used to specify the converter object that is called by the binding engine to modify the data as it is passed between the source and the destination.
  • Converter Culture specifies a parameter that can be passed to the conversion of the data.
  • Conversion Parameter specifies a parameter that can be passed to the converter.

What is DataContext?

There is one more important thing in database binding, which is the DataContext property. The DataContext property is used to set or get the data context for a FrameworkElement when it is participate in data binding.

Data context is inherited. If you set the data context on a parent element, all its children will use the same data context. A child element can override this behavior by setting the Source property on its binding object or by setting its DataContext, which will then apply to all its children.

The DataContext property can be set in the parent control or for each child control. The only advantage of setting it in the parent control is, you don’t need to repeat it for each child control.

Here is an example of how to set the DataContext property in the parent control and use it in the child controls.

BindingModesExamples.xaml
<UserControl x:Class="SampleCode.BindingModesExamples"
     xmlns:local="clr-namespace:SampleCode"
     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"    >
   <UserControl.Resources>
       <local:Employee x:Key="employeeInfo" FirstName="Anjaiah" LastName="Keesari"/>
   </UserControl.Resources>  
   <Grid x:Name="LayoutRoot" 
      DataContext="{StaticResource employeeInfo}" 
      Background="LightCyan" Width="500" Height="300" 
      HorizontalAlignment="Left" >
        <Grid.ColumnDefinitions >
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        
        <TextBlock Text="First Name" Grid.Column="1" Grid.Row="1"></TextBlock>
        <TextBox x:Name="tbFirstName" Text="{Binding Path=FirstName, Mode=OneTime}" 
                 Grid.Column="2" Grid.Row="1"></TextBox>
        
        <TextBlock Text="Last Name" Grid.Column="1" Grid.Row="2"></TextBlock>
        <TextBox x:Name="tbLastName" Text="{Binding Path=LastName, Mode=OneTime}" 
                 Grid.Column="2" Grid.Row="2"></TextBox>
        
        <TextBlock Text="Email ID" Grid.Column="1" Grid.Row="3"></TextBlock>
        <TextBox x:Name="tbEmailID" Text="{Binding Path=EmailID, Mode=OneTime}" 
                 Grid.Column="2" Grid.Row="3"></TextBox>
    </Grid>
</UserControl>

Most of the times, you may not want to bind the data just using XAML; you can also do the same thing using your favorite programming language like C#. Binding can also be performed programmatically. What you need to do is just create a new binding object and call the SetBinding() method to perform the binding between the source and the target. Here is a sample code to do that.

BindingModesExamples.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.Windows.Data;
namespace SampleCode
{
    public partial class BindingModesExamples : UserControl
    {
        public BindingModesExamples()
        {
            InitializeComponent();
            Loaded+=new RoutedEventHandler(BindingModesExamples_Loaded);
        }
        //Example of binding useing code 
        private void BindingModesExamples_Loaded(object sender, RoutedEventArgs args)
        {
            Employee employee = new Employee();
            employee.EmailID = "Keesari_anjaiah@yahoo.co.in";
            Binding binding = new Binding()
            {
                Source = employee,
                Path = new PropertyPath("EmailID"),
                Mode = BindingMode.OneTime
            };
            tbEmailID.SetBinding(TextBox.TextProperty, binding);
        }
    }
}

Before we proceed further, let me show you the .NET object which I am using for each example. Do not worry about the PropertyChanged concepts in this class which we will be talking about soon. Just continue reading this article completely in order to understand the data binding concepts.

Employee.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace SampleCode
{
    public class Employee :INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }
        private int employeeID;
        public int EmployeeID
        {
            get
            {
                return employeeID;
            }
            set
            {
                if (employeeID != value)
                {
                    employeeID = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("EmployeeID"));
                }
            }
        }
        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set
            {
                if (firstName != value)
                {
                    firstName = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("FirstName"));
                }
            }
        }
        private string lastName;
        public string LastName
        {
            get { return lastName; }
            set
            {
                if (lastName != value)
                {
                    lastName = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("LastName"));
                }
            }
        }
        private String emailID;
        public String EmailID
        {
            get
            {
                return emailID;
            }
            set
            {
                if (emailID != value)
                {
                    emailID = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("EmailID"));
                }
            }
        }
        private string title;
        public string Title
        {
            get { return title; }
            set
            {
                if (title != value)
                {
                    title = value;
                    OnPropertyChanged(new PropertyChangedEventArgs ("Title"));
                }
            }
        }
        private DateTime dateOfBirth;
        public DateTime DateOfBirth {
            get { return dateOfBirth; }
            set {
                if (dateOfBirth != value)
                {
                    dateOfBirth = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("DateOfBirth"));
                }
            }
        }
    }
}
Output:

Binding Collections

Now that we are clear on single object data binding, let’s talk about collections of objects.

ListBox is one of the controls used to bind collections of data. All collection control classes are represented by the ItemsControl class. Binding a collection to an ItemsControl is as simple as assigning the ItemsSource property to some collection and assigning the DisplayMemberPath to a property of a collection item.

TwoWayBindingExamples.xaml
<UserControl x:Class="SampleCode.TwoWayBindingExamples"
    xmlns:local="clr-namespace:SampleCode"
    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">
    <UserControl.Resources>
        <local:Employees  x:Key="Employees" />
    </UserControl.Resources>
    <StackPanel DataContext="{StaticResource Employees}" 
              Background="LightCyan" Width="500" Height="300" >
        <TextBox x:Name="tbDescription"
            Text="{Binding Path=SelectedItem.Title, ElementName=lbEmployees, Mode=TwoWay}"
            HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Width="325" />
        <ListBox x:Name="lbEmployees" ItemsSource="{Binding}"
            DisplayMemberPath="Title" HorizontalAlignment="Left" VerticalAlignment="Top"
            Margin="10" Width="323" />
    </StackPanel>
</UserControl>
Employees.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace SampleCode
{
    public class Employees : ObservableCollection<Employee>
    {
        public Employees()
        {
            this.Add(new Employee()
            {
                EmployeeID=1,
                FirstName = "Nancy",
                LastName = "Davolio",
                Title = "Sales Representative",
            });
            this.Add(new Employee()
            {
                EmployeeID = 2,
                FirstName = "Andrew",
                LastName = "Fuller",
                Title = "Vice President, Sales",
            });
            this.Add(new Employee()
            {
                EmployeeID = 3,
                FirstName = "Janet",
                LastName = "Leverling",
                Title = "Sales Manager",
            });
        }
    }
}

Change Notification

As we discussed earlier, we need to allow changes made in the data source to reflect immediately on the target. How is this possible? This is possible by implementing the INotifyPropertyChanged interface. It is a descendent of ObservableCollection<T>, and the interface is implemented for you. What you need to do is take the namespace System.ComponentModel to implement INotifyPropertyChanged interface.  This has the single method called PropertyChanged(). When setting a property value, you need to call the OnPropertyChanged() method if any value changes.

ObservableCollection

To provide notifications for collection changes (new item added, removed, or entire list refreshed), we need to inherit our collection object from ObservableCollection<T>. Add a reference to System.Collections.ObjectModel before using ObservableCollection.

Silverlight provides the ObservableCollection<T> class, which is a base class data collection that implements the INotifyCollectionChanged interface, as well as the INotifyPropertyChanged interface. It also has the expected collection support, defined by deriving from the Collection<T> class.

Note: Update occurs when the TextBox loses focus.

Output:

Conclusion

I hope you enjoyed my article. Please do not forget to write your comments on this article, which is very important for me.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author


Comments and Discussions

 
GeneralNice Article PinprofessionalSnesh Prajapati24-Jun-14 23:44 
QuestionVery nice article PinmemberArul Dinesh CERPS11-Apr-14 1:55 
QuestionExcellent PinmemberMember 1040058818-Dec-13 7:41 
Questionnice article PinmemberJagz W22-Jan-13 18:41 
GeneralMy vote of 5 PinmemberUday P.Singh14-Jan-13 0:48 
GeneralMy vote of 5 Pinmemberkaminianand17-Dec-12 2:08 
GeneralMy vote of 5 Pinmemberkaminianand14-Nov-12 2:56 
GeneralHi... Pinmembersiddu618-Jul-12 0:01 
SuggestionSource Code? Pinmemberdenpsia26-Apr-12 22:57 
GeneralMy vote of 5 Pinmemberbriij20-Jan-12 20:40 
SuggestionHi! PinmemberMember 801035420-Sep-11 22:45 
QuestionSimple databinding in silverlight Pinmemberawadhendra tiwari27-Aug-11 2:40 
GeneralMy vote of 5 Pinmembersharad_rtm13-Feb-11 21:45 
GeneralGood article. PinmemberSuresh Pedireddi4-Oct-10 7:14 
GeneralThanks PinmemberOscar Rivera24-May-10 12:39 
GeneralThanks Pinmemberryall19-May-10 15:53 
QuestionPreference of code over XAML? Pinmembertec-goblin18-May-10 1:07 
Very good article, nice use of images, a great introduction.
Still you say
"Most of the times, you may not want to bind the data just using XAML"
I don't see why. Whenever I can say something declaratively, I prefer it, keeping the code as clean as possible, and not caring about timing (because binding programmatically actually needs to be performed during a particular event of the control lifecycle, a detail that's conventionally hidden when you do it declaratively.
 
You could say "If you prefer, you can bind data without using XAML..."
GeneralThanks! Pinmembermicahs12-May-10 16:04 
GeneralGood use of graphics Pinmemberdefwebserver11-May-10 14:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411023.1 | Last Updated 11 May 2010
Article Copyright 2010 by keesari_anjaiah
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid