Simple Example on Binding and UpdateSourceTrigger Property in WPF

Introduction

This is my first Article on WPF. The idea of writing this article is to give a basic understanding for the beginners on Bindings and the main use of UpdateSourceTrigger property.

In this Article we are going to see how binding works and Whats the main use of UpdateSourceTrigger property to raise and to respond to changes.

Use of PropertyChanged attribute in UpdateSourceTrigger event:

In simple terms this is one of the property which is used in bindings in Wpf. This property defines the timing of binding source updates.

This is nothing but the communication between Source and the target. Deals with how source is updated when target changes.

In this example we are going to see how the entered EmployeeName (target) will be shown in Text block (Source) which is below.

There are two binding modes which updates the source i.e OnewaytoSource and Two Way.

UpdateSourceTrigger Property has properties like below:

  • Default
  • LostFocus
  • Explicit
  • PropertyChanged

Let us go through a quick and simple Example by step by step.

Open Visual Studio à File -à New -à Project -à Select WPF Application

Give the name of the Project and Click OK.

Lets create a sample UI to enter the basic Employee Details with bindings and later we are going to display the data in the DataGrid

MainWindow.xaml

  1. <Window x:Class="Adding_To_DataGrid.MainWindow"  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.  Title="MainWindow" Height="450" Width="680">  
  5.     <Grid Background="LightGray">  
  6.         <Grid.RowDefinitions>  
  7.             <RowDefinition Height="Auto"/>  
  8.             <RowDefinition Height="220"/>  
  9.             <RowDefinition Height="40"/>  
  10.             <RowDefinition Height="60"/>  
  11.         </Grid.RowDefinitions>  
  12.         <DataGrid Name="dgDataGrid" Grid.Row="0" AutoGenerateColumns="False" Background="LightGray" Margin="5,15">  
  13.             <DataGrid.Columns>  
  14.                 <DataGridTextColumn Header="Employee ID"/>  
  15.                 <DataGridTextColumn Header="Employee Name" />  
  16.                 <DataGridTextColumn Header="EmployeeDepartment" />  
  17.                 <DataGridTextColumn Header="Employee Designation" />  
  18.                 <DataGridTextColumn Header="Contact Number"/>  
  19.                 <DataGridTextColumn Header="Employee Location" />  
  20.             </DataGrid.Columns>  
  21.         </DataGrid>  
  22.         <Grid Grid.Row="1" Background="LightBlue" Margin="6,30">  
  23.             <Grid.RowDefinitions>  
  24.                 <RowDefinition Height="50"/>  
  25.                 <RowDefinition Height="50"/>  
  26.                 <RowDefinition Height="50"/>  
  27.                 <RowDefinition Height="50"/>  
  28.             </Grid.RowDefinitions>  
  29.             <Grid.ColumnDefinitions>  
  30.                 <ColumnDefinition Width="150"/>  
  31.                 <ColumnDefinition Width="150"/>  
  32.                 <ColumnDefinition Width="150"/>  
  33.                 <ColumnDefinition Width="160"/>  
  34.             </Grid.ColumnDefinitions>  
  35.             <Label Name="lbEmpID" Content="Employee ID" Grid.Row="0" Grid.Column="0" Height="30"/>  
  36.             <TextBox Name="tbEmpID" Height="30" Grid.Row="0" Grid.Column="1" />  
  37.             <Label Name="lbEmpName" Height="30" Content="Employee Name" Grid.Row="0" Grid.Column="2"/>  
  38.             <TextBox Name="tbEmpName" Height="30" Grid.Row="0" Grid.Column="3" />  
  39.             <Label Name="lbEmpDepartment" Height="30" Content="Employee Department" Grid.Row="1" Grid.Column="0"/>  
  40.             <TextBox Name="tbEmpDepartment" Height="30" Grid.Row="1" Grid.Column="1"/>  
  41.             <Label Name="lbEmpDesignation" Height="30" Content="Employee Designation" Grid.Row="1" Grid.Column="2"/>  
  42.             <TextBox Name="tbEmpDesignation" Height="30" Grid.Row="1" Grid.Column="3"/>  
  43.             <Label Name="lbEmpContactNo" Height="30" Content="Contact Number" Grid.Row="2" Grid.Column="0"/>  
  44.             <TextBox Name="tbEmpContactNo" Height="30" Grid.Row="2" Grid.Column="1"/>  
  45.             <Label Name="lbEmpLocation" Height="30" Content="Employee Location" Grid.Row="2" Grid.Column="2"/>  
  46.             <TextBox Name="tbEmpLocation" Height="30" Grid.Row="2" Grid.Column="3"/>  
  47.         </Grid>  
  48.         <StackPanel Orientation="Horizontal" Grid.Row="2" Height="40" Width="250">  
  49.             <Button Name="btnSubmit" Content="Submit" Click="btnSubmit_Click" Width="100" Height="30" FontSize="14"/>  
  50.             <Button Name="btnClearGrid" Content="ClearGrid" Click="btnClearGrid_Click" Width="100" Height="30" Margin="20,0,0,0"/>  
  51.         </StackPanel>  
  52.         <StackPanel Grid.Row="3" Orientation="Horizontal">  
  53.             <Label Content="You have given the Employee name as.." FontSize="14" Foreground="Green" FontWeight="Bold" Height="30" Margin="10,0,0,0"/>  
  54.             <TextBlock Name="tbText" FontSize="16" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"  
  55.  Height="50" Width="250" Padding="15"/>  
  56.         </StackPanel>  
  57.     </Grid>  
  58. </Window>  
Now we will create a ViewModel class with some properties which is used for bindings in our Xaml. This class inherits INotifyPropertyChanged event to raise and to respond to changes for us. By this property it will notify whenever a data is changed. Here will see how to see the entered Employee name in anothere Textblock by using PropertyChanged Event. For this

Go to Project Right Click Add Class and Give Class name as EmployeeViewModel.cs

Please See the class with properties event below.

EmployeeViewModel.cs

  1. public class EmployeeViewModel   
  2. {  
  3.     private string _employeeID = string.Empty;  
  4.     public string EmployeeID   
  5.     {  
  6.         get   
  7.         {  
  8.             return _employeeID;  
  9.         }  
  10.         set   
  11.         {  
  12.             _employeeID = value;  
  13.         }  
  14.     }  
  15.     private string _employeeName = string.Empty;  
  16.     public string EmployeeName   
  17.     {  
  18.         get   
  19.         {  
  20.             return _employeeName;  
  21.         }  
  22.         set   
  23.         {  
  24.             _employeeName = value;  
  25.         }  
  26.     }  
  27.     private string _employeeDepartment = string.Empty;  
  28.     public string EmployeeDepartment  
  29.     {  
  30.         get   
  31.         {  
  32.             return _employeeDepartment;  
  33.         }  
  34.         set   
  35.         {  
  36.             _employeeDepartment = value;  
  37.         }  
  38.     }  
  39.     private string _employeeDesignation = string.Empty;  
  40.     public string EmployeeDesignation  
  41.     {  
  42.         get   
  43.         {  
  44.             return _employeeDesignation;  
  45.         }  
  46.         set   
  47.         {  
  48.             _employeeDesignation = value;  
  49.         }  
  50.     }  
  51.     private string _employeeContactNo = string.Empty;  
  52.     public string EmployeeContactNo   
  53.     {  
  54.         get   
  55.         {  
  56.             return _employeeContactNo;  
  57.         }  
  58.         set  
  59.         {  
  60.             _employeeContactNo = value;  
  61.         }  
  62.     }  
  63.     private string _employeeLocation = string.Empty;  
  64.     public string EmployeeLocation  
  65.     {  
  66.         get   
  67.         {  
  68.             return _employeeLocation;  
  69.         }  
  70.         set  
  71.         {  
  72.          _employeeLocation = value;  
  73.         }  
  74.     }  
  75.  
Now these properties we will use in bindings in our Xaml by using UpdateSourceTrigger property.

If we give UpdateSourceTrigger as PropertyChanged then the value update will happen whenever a target propery changes. It usually happens for every key stroke.

Now I am giving EmployeeName Textbox binding with UpdateSourceTrigger as "Property Changed". And I am going to display the EmployeeName below asynchronously.

Let us see how to give bindings in our Xaml by using this property . Now our complete Xaml looks like below.

MainWindow.xaml

  1. <Window x:Class="BindingsWithINotifyProperyChangedSample.MainWindow"  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.  Title="MainWindow" Height="400" Width="680">  
  5.     <Grid Background="LightGray">  
  6.         <Grid.RowDefinitions>  
  7.             <RowDefinition Height="Auto"/>  
  8.             <RowDefinition Height="220"/>  
  9.             <RowDefinition Height="40"/>  
  10.             <RowDefinition Height="60"/>  
  11.         </Grid.RowDefinitions>  
  12.         <DataGrid Name="dgDataGrid" Grid.Row="0" AutoGenerateColumns="False" Background="LightGray" Margin="5,15">  
  13.             <DataGrid.Columns>  
  14.                 <DataGridTextColumn Header="Employee ID" Binding="{Binding EmployeeID}"/>  
  15.                 <DataGridTextColumn Header="Employee Name" Binding="{Binding EmployeeName}"/>  
  16.                 <DataGridTextColumn Header="EmployeeDepartment" Binding="{Binding EmployeeDepartment}"/>  
  17.                 <DataGridTextColumn Header="Employee Designation" Binding="{Binding EmployeeDesignation}"/>  
  18.                 <DataGridTextColumn Header="Contact Number" Binding="{Binding EmployeeContactNo}"/>  
  19.                 <DataGridTextColumn Header="Employee Location" Binding="{Binding EmployeeLocation}"/>  
  20.             </DataGrid.Columns>  
  21.         </DataGrid>  
  22.         <Grid Grid.Row="1" Background="LightBlue" Margin="6,30">  
  23.             <Grid.RowDefinitions>  
  24.                 <RowDefinition Height="50"/>  
  25.                 <RowDefinition Height="50"/>  
  26.                 <RowDefinition Height="50"/>  
  27.                 <RowDefinition Height="50"/>  
  28.             </Grid.RowDefinitions>  
  29.             <Grid.ColumnDefinitions>  
  30.                 <ColumnDefinition Width="150"/>  
  31.                 <ColumnDefinition Width="150"/>  
  32.                 <ColumnDefinition Width="150"/>  
  33.                 <ColumnDefinition Width="160"/>  
  34.             </Grid.ColumnDefinitions>  
  35.             <Label Name="lbEmpID" Content="Employee ID" Grid.Row="0" Grid.Column="0" Height="30"/>  
  36.             <TextBox Name="tbEmpID" Height="30" Grid.Row="0" Grid.Column="1" />  
  37.             <Label Name="lbEmpName" Height="30" Content="Employee Name" Grid.Row="0" Grid.Column="2"/>  
  38.             <TextBox Name="tbEmpName" Height="30" Grid.Row="0" Grid.Column="3" Text="{Binding EmployeeName, UpdateSourceTrigger=PropertyChanged}"/>  
  39.             <Label Name="lbEmpDepartment" Height="30" Content="Employee Department" Grid.Row="1" Grid.Column="0"/>  
  40.             <TextBox Name="tbEmpDepartment" Height="30" Grid.Row="1" Grid.Column="1"/>  
  41.             <Label Name="lbEmpDesignation" Height="30" Content="Employee Designation" Grid.Row="1" Grid.Column="2"/>  
  42.             <TextBox Name="tbEmpDesignation" Height="30" Grid.Row="1" Grid.Column="3"/>  
  43.             <Label Name="lbEmpContactNo" Height="30" Content="Contact Number" Grid.Row="2" Grid.Column="0"/>  
  44.             <TextBox Name="tbEmpContactNo" Height="30" Grid.Row="2" Grid.Column="1"/>  
  45.             <Label Name="lbEmpLocation" Height="30" Content="Employee Location" Grid.Row="2" Grid.Column="2"/>  
  46.             <TextBox Name="tbEmpLocation" Height="30" Grid.Row="2" Grid.Column="3"/>  
  47.         </Grid>  
  48.         <StackPanel Orientation="Horizontal" Grid.Row="2" Height="40" Width="250">  
  49.             <Button Name="btnSubmit" Content="Submit" Click="btnSubmit_Click" Width="100" Height="30" FontSize="14"/>  
  50.             <Button Name="btnClearGrid" Content="ClearGrid" Click="btnClearGrid_Click" Width="100" Height="30" Margin="20,0,0,0"/>  
  51.         </StackPanel>  
  52.         <StackPanel Grid.Row="3" Orientation="Horizontal">  
  53.             <Label Content="You have given the Employee name as.." FontSize="14" Foreground="Green" FontWeight="Bold" Height="30" Margin="10,0,0,0"/>  
  54.             <TextBlock Name="tbText" Text="{Binding EmployeeName}" FontSize="16" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"  
  55.  Height="50" Width="250" Padding="15"/>  
  56.         </StackPanel>  
  57.     </Grid>  
  58. </Window>  
Since I gave UpdateSourceTrigger as PropertyChanged for Employee TextBox, the entered Employee Name will be displayed in the TextBlock below at the same time. Its notifying us that the value is changed in the Employee Textbox.

Note : If we remove UpdateSourceTrigger as "PropertyChanged" then the entered Employee name will not be shown in the TextBlock below for us. Thats plays a major role here..

Lets go to our Codebehind to write for Click events and code to display the data in our datagrid.

In the constructor we are giving the ViewModel object as DataContext like below

  1. public MainWindow()  
  2. {  
  3.     this.DataContext = new EmployeeViewModel();  
  4.     InitializeComponent();  
  5. }  
After entering the data in the textboxes and when we click on Submit button, the data will be displayed in our Datagrid .

Just to clear the data in the DataGrid we are using a Clear button here.

The whole codebehind looks like below.

MainWindow.xaml.cs

  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. namespace Adding_To_DataGrid  
  15. {  
  16.     /// <summary>  
  17.     /// Interaction logic for MainWindow.xaml  
  18.     /// </summary>  
  19.     public partial class MainWindow: Window   
  20.     {  
  21.         public MainWindow()   
  22.         {  
  23.             this.DataContext = new EmployeeViewModel();  
  24.             InitializeComponent();  
  25.         }  
  26.   
  27.         private void btnSubmit_Click(object sender, RoutedEventArgs e)   
  28.         {  
  29.             AddToGrid();  
  30.         }  
  31.         public void AddToGrid()   
  32.         {  
  33.             List < EmployeeViewModel > empCollection = new List < EmployeeViewModel > ();  
  34.             empCollection.Add(new EmployeeViewModel() {  
  35.                 EmployeeID = Convert.ToInt32(tbEmpID.Text),  
  36.                 EmployeeName = tbEmpName.Text,  
  37.                 EmployeeDepartment = tbEmpDepartment.Text,  
  38.                 EmployeeDesignation = tbEmpDesignation.Text,  
  39.                 EmployeeContactNo = tbEmpContactNo.Text,  
  40.                 EmployeeLocation = tbEmpLocation.Text  
  41.             });  
  42.             dgDataGrid.Items.Add(empCollection);  
  43.             ClearFields();  
  44.         }  
  45.         public void ClearFields()   
  46.         {  
  47.             tbEmpID.Text = "";  
  48.             tbEmpName.Text = "";  
  49.             tbEmpDepartment.Text = "";  
  50.             tbEmpDesignation.Text = "";  
  51.             tbEmpContactNo.Text = "";  
  52.             tbEmpLocation.Text = "";  
  53.         }  
  54.         private void btnClearGrid_Click(object sender, RoutedEventArgs e)   
  55.         {  
  56.             dgDataGrid.Items.Clear();  
  57.         }  
  58.     }  
  59. }  
Please Note : If we give UpdateSourceTrigger as LostFocus then the data will be updated in the TextBlock once the focus is lost in the Employee TextBox

If we give UpdateSourceTrigger as Explicit then the Binding Source is updated only when BindingExpression.UpdateSource() method is called explicitly 

To check this please add one button and write the click event for the button lie below.

  1. private void btnExplicit_Click(object sender, RoutedEventArgs e)  
  2. {  
  3.   
  4. //Replace it with your TextBox name  
  5. BindingExpression obj = tbEmpName.GetBindingExpression(TextBox.TextProperty); obj.UpdateSource();  
  6.   
  7. }  
Now in this Article I hope you understand how simple binding works and how the text updated by using UpdateSourceTrigger as PropertyChanged. Please rate this simple Article if you like…

Please download the full Sample .

Happy Coding !!!