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.
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.
- Derive the class exposing the properties from INotifyPropertChanged.
- Declare the event. Ex: public event PropertyChangedEventHandler PropertyChanged;
- Call OnPropertyChanged nd pass the property name whenever the property is updated Ex: OnPropertyChanged("EmployeeName");
- 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));
}
}
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using System.ComponentModel;
- namespace Bindingtoclasses
- {
- public partial class MainWindow : Window
- {
- public MainWindow()
- {
- InitializeComponent();
- Employee P = new Employee("Hello World");
- this.DataContext = P;
- }
- }
- // This class implements INotifyPropertyChanged to support one-way and two-way bindings
- // (such that the UI element updates when the source has been changed dynamically)
- public class Employee : INotifyPropertyChanged
- {
- private string name;
- // Declare the event
- public event PropertyChangedEventHandler PropertyChanged;
- public Employee()
- {
- }
- public Employee(string value)
- {
- this.name = value;
- }
- public string EmployeeName
- {
- get { return name; }
- set
- {
- name = value;
- // Call OnPropertyChanged whenever the property is updated
- OnPropertyChanged("EmployeeName");
- }
- }
- //// Create the OnPropertyChanged method to raise the event
- protected void OnPropertyChanged(string name)
- {
- PropertyChangedEventHandler handler = PropertyChanged;
- if (handler != null)
- {
- handler(this, new PropertyChangedEventArgs(name));
- }
- }
- }
- }
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.
- 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> - 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;
} - 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.
- 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.
- 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.
- Line 18 uses DataContext and so uses the EmployeeName property directly and binds to textbox3.
Code Snippet
- <Window x:Class="Bindingtoclasses.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:src="clr-namespace:Bindingtoclasses"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <Grid.Resources>
- <src:Employee x:Key="myDataSource" EmployeeName="Kishore1021"/>
- </Grid.Resources>
- <Grid.RowDefinitions>
- <RowDefinition Height="*"></RowDefinition>
- <RowDefinition Height="*"></RowDefinition>
- <RowDefinition Height="*"></RowDefinition>
- </Grid.RowDefinitions>
- <TextBox Grid.Row="0" Text="{Binding Source={StaticResource myDataSource}, Path=EmployeeName, UpdateSourceTrigger=PropertyChanged}"/>
- <TextBox Grid.Row="1" Text="{Binding Source= {StaticResource myDataSource}, Path=EmployeeName}"></TextBox>
- <TextBox Grid.Row="2" Text="{Binding Path=EmployeeName}"></TextBox>
- </Grid>
- </Window>
The output of the program is as follows
Pingback: DataContext in WPF « Kishore – Software Architect, Washington DC
Pingback: Data Binding–Source & Target « Kishore – Software Architect, Washington DC
Pingback: Introduction to Multi Binding and Multi value converter using IMultiValueConverter & MultiBinding « Kishore – Software Architect, Washington DC
Pingback: Introduction to Command Binding « Kishore – Software Architect, Washington DC