Monthly Archives: January 2011

ABCs of Data Binding

Building the presentation (User Interface) applications is all about displaying and manipulation of data. Well, WPF has a powerful feature to display data in UI controls that can be bound to the data present in our control (business) or entity (data) classes or any class data for that matter.

Suppose you have a class called person and it has a property  public string PersonName that you want to display in a text box. How do we bind these two objects together? Well, WPF’s DataBinding comes to the rescue. Each binding has these four components:

  • A binding target object
  • A target property
  • A binding source
  • A path to the value in the binding source to use.

For example,if you want to bind the content of a TextBox to the Name property of an employee object, your target object is the TextBox, the target property is the Text property, the value to use is EmployeeName, and the source object is the employee object. The following figure illustrates the concepts of DataBinding.

 

image

Figure 1: Components of DataBinding

Mode Property:

You use the Mode property to specify the direction of the binding, i.e. source -> target or target <- source. The following enumeration list shows the available options for binding

  • Default causes the default Mode value of target property to be used.
  • OneTime updates the target property only when the application starts or when the DataContext undergoes a change.
  • OneWay updates the target property only when the source property changes.
  • TwoWay updates the target property or the property whenever either the target property or the source property changes.
  • OneWayToSource updates the source property when the target property changes.

UpdateSourceTrigger Property:

The UpdateSourceTrigger property of the binding determines what triggers the update of the source. If you a bind a variable to a control, then the data from the control can be transferred to the variable by using this property.

  • Default: Any of the following values (Depends on the control)
  • Explicit:The Source Value Gets Updated when the appications calls UpdateSource
  • LostFocus: The Source Value Gets Updated when the UIElement control loses focus
  • PropertyChanged:The Source Value Gets Updated when the user types in the UIElement control

Following is the code of the employee class that exposes a property called EmployeeName that we want to bind to the textbox control. To make binding happen, the following should be implemented on the data class.

  1. Derive the class exposing the properties from INotifyPropertChanged.
  2. Declare the event. Ex: public event PropertyChangedEventHandler PropertyChanged;
  3. Call OnPropertyChanged nd pass the property name whenever the property is updated Ex: OnPropertyChanged("EmployeeName");
  4. Create the OnPropertyChanged method to raise the event. Ex:
            protected void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(name));
                }
            }
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14. using System.ComponentModel;
  15.  
  16. namespace Bindingtoclasses
  17. {
  18.     public partial class MainWindow : Window
  19.     {
  20.         public MainWindow()
  21.         {
  22.             InitializeComponent();
  23.             Employee P = new Employee("Hello World");
  24.             this.DataContext = P;
  25.         }
  26.     }
  27.  
  28.     // This class implements INotifyPropertyChanged to support one-way and two-way bindings
  29.     // (such that the UI element updates when the source has been changed dynamically)
  30.     public class Employee : INotifyPropertyChanged
  31.     {
  32.         private string name;
  33.         // Declare the event
  34.         public event PropertyChangedEventHandler PropertyChanged;
  35.  
  36.         public Employee()
  37.         {
  38.         }
  39.  
  40.         public Employee(string value)
  41.         {
  42.             this.name = value;
  43.         }
  44.  
  45.         public string EmployeeName
  46.         {
  47.             get { return name; }
  48.             set
  49.             {
  50.                 name = value;
  51.                 // Call OnPropertyChanged whenever the property is updated
  52.                OnPropertyChanged("EmployeeName");
  53.             }
  54.         }
  55.  
  56.         //// Create the OnPropertyChanged method to raise the event
  57.         protected void OnPropertyChanged(string name)
  58.         {
  59.             PropertyChangedEventHandler handler = PropertyChanged;
  60.             if (handler != null)
  61.             {
  62.                 handler(this, new PropertyChangedEventArgs(name));
  63.             }
  64.         }
  65.     }
  66.  
  67. }

The XAML code to bind the class property to the textbox controls is as follows. To make binding happen, the following should be implemented in the XAML code.

  1. First we need to create an object of the employee class in XAML in the parent element. Ex:
    <Grid.Resources>
            <src:Employee x:Key="myDataSource" EmployeeName="Kishore1021"/>
    </Grid.Resources>

  2. Instead of creating an object in XAML, we can also use DataContext property, create an employee object in the code and assign it to the DataContext as follows
            public MainWindow()
            {
                InitializeComponent();
                Employee P = new Employee("Hello World");
                this.DataContext = P;
            }

  3. I used both in the following sample . Line 16 and 17 uses the local object created in XAML and line 18 uses the DataContext and so directly uses the property name. More info on DataContext in the coming blogs.
  4. Use the Binding Markup Extension “{Binding}” and key in the parameters. In Line 16, I am binding the TextBox.Text to myDataSource object and in that object, I am binding to EmployeeName and the source gets updated when the property gets changed. So as you type, the text in textbox2 also gets changed.
  5. Line 17 also uses the same concept as above except that it doesn’t update the source as the user types. Since the default value of updateSourceTrigger binding property is LostFocus, the textbox1 gets updated only when textbox2 loses focus.
  6. Line 18 uses DataContext and so uses the EmployeeName property directly and binds to textbox3.
    Code Snippet
    1. <Window x:Class="Bindingtoclasses.MainWindow"
    2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
    4.         xmlns:src="clr-namespace:Bindingtoclasses"
    5.  
    6.         Title="MainWindow" Height="350" Width="525">
    7.     <Grid>
    8.         <Grid.Resources>
    9.                 <src:Employee x:Key="myDataSource" EmployeeName="Kishore1021"/>
    10.         </Grid.Resources>
    11.         <Grid.RowDefinitions>
    12.             <RowDefinition Height="*"></RowDefinition>
    13.             <RowDefinition Height="*"></RowDefinition>
    14.             <RowDefinition Height="*"></RowDefinition>
    15.         </Grid.RowDefinitions>
    16.         <TextBox Grid.Row="0" Text="{Binding Source={StaticResource myDataSource}, Path=EmployeeName, UpdateSourceTrigger=PropertyChanged}"/>
    17.         <TextBox Grid.Row="1" Text="{Binding Source= {StaticResource myDataSource}, Path=EmployeeName}"></TextBox>
    18.         <TextBox Grid.Row="2" Text="{Binding Path=EmployeeName}"></TextBox>
    19.         
    20.     </Grid>
    21. </Window>

The output of the program is as follows

image

Download code from Microsoft Skydrive :

Direct Link : https://skydrive.live.com/redir.aspx?cid=38ecce05b21b8b44&amp;resid=38ECCE05B21B8B44!394&amp;parid=38ECCE05B21B8B44!393

"If you’re riding ahead of the herd, take a look back every now and then to make sure it’s still there" – Will Rogers