Introduction
This is my first article on WPF. The idea of writing this article is to give a basic understanding for beginners on Bindings and the main use of UpdateSourceTrigger
property.
In this article, we are going to see how binding works and what's 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 properties 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 target. It deals with how source is updated when the 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 update the source, i.e., OnewaytoSource
and TwoWay
.
UpdateSourceTrigger
property has properties like below:
Default
LostFocus
Explicit
PropertyChanged
Let us go through a quick and simple example in a step by step manner.
Open Visual Studio --> File -> New -> Project --> Select WPF Application
Give the name of the Project and Click OK.
Let's 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
<Window x:Class="Adding_To_DataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="680">
<Grid Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="220"/>
<RowDefinition Height="40"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<DataGrid Name="dgDataGrid"
Grid.Row="0" AutoGenerateColumns="False"
Background="LightGray" Margin="5,15">
<DataGrid.Columns>
<DataGridTextColumn Header="Employee ID"/>
<DataGridTextColumn Header="Employee Name" />
<DataGridTextColumn Header="EmployeeDepartment" />
<DataGridTextColumn Header="Employee Designation" />
<DataGridTextColumn Header="Contact Number"/>
<DataGridTextColumn Header="Employee Location" />
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Row="1" Background="LightBlue" Margin="6,30">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="160"/>
</Grid.ColumnDefinitions>
<Label Name="lbEmpID" Content="Employee ID"
Grid.Row="0" Grid.Column="0" Height="30"/>
<TextBox Name="tbEmpID" Height="30"
Grid.Row="0" Grid.Column="1" />
<Label Name="lbEmpName" Height="30"
Content="Employee Name" Grid.Row="0" Grid.Column="2"/>
<TextBox Name="tbEmpName" Height="30"
Grid.Row="0" Grid.Column="3" />
<Label Name="lbEmpDepartment" Height="30"
Content="Employee Department" Grid.Row="1" Grid.Column="0"/>
<TextBox Name="tbEmpDepartment" Height="30"
Grid.Row="1" Grid.Column="1"/>
<Label Name="lbEmpDesignation" Height="30"
Content="Employee Designation" Grid.Row="1"
Grid.Column="2"/>
<TextBox Name="tbEmpDesignation" Height="30"
Grid.Row="1" Grid.Column="3"/>
<Label Name="lbEmpContactNo" Height="30"
Content="Contact Number" Grid.Row="2" Grid.Column="0"/>
<TextBox Name="tbEmpContactNo" Height="30"
Grid.Row="2" Grid.Column="1"/>
<Label Name="lbEmpLocation" Height="30"
Content="Employee Location" Grid.Row="2"
Grid.Column="2"/>
<TextBox Name="tbEmpLocation" Height="30"
Grid.Row="2" Grid.Column="3"/>
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="2"
Height="40" Width="250">
<Button Name="btnSubmit" Content="Submit"
Click="btnSubmit_Click"
Width="100" Height="30" FontSize="14"/>
<Button Name="btnClearGrid" Content="ClearGrid"
Click="btnClearGrid_Click"
Width="100" Height="30" Margin="20,0,0,0"/>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal">
<Label Content="You have given the Employee name as.."
FontSize="14" Foreground="Green"
FontWeight="Bold" Height="30" Margin="10,0,0,0"/>
<TextBlock Name="tbText" FontSize="16"
FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" VerticalAlignment="Center"
Height="50" Width="250" Padding="15"/>
</StackPanel>
</Grid>
</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, we will see how to see the entered Employee
name in another 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
public class EmployeeViewModel
{
private string _employeeID = string.Empty;
public string EmployeeID
{
get
{
return _employeeID;
}
set
{
_employeeID = value;
}
}
private string _employeeName = string.Empty;
public string EmployeeName
{
get
{
return _employeeName;
}
set
{
_employeeName = value;
}
}
private string _employeeDepartment = string.Empty;
public string EmployeeDepartment
{
get
{
return _employeeDepartment;
}
set
{
_employeeDepartment = value;
}
}
private string _employeeDesignation = string.Empty;
public string EmployeeDesignation
{
get
{
return _employeeDesignation;
}
set
{
_employeeDesignation = value;
}
}
private string _employeeContactNo = string.Empty;
public string EmployeeContactNo
{
get
{
return _employeeContactNo;
}
set
{
_employeeContactNo = value;
}
}
private string _employeeLocation = string.Empty;
public string EmployeeLocation
{
get
{
return _employeeLocation;
}
set
{
_employeeLocation = value;
}
}
}
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 property changes. It usually happens for every keystroke.
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
<Window x:Class="BindingsWithINotifyProperyChangedSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="680">
<Grid Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="220"/>
<RowDefinition Height="40"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<DataGrid Name="dgDataGrid" Grid.Row="0"
AutoGenerateColumns="False" Background="LightGray" Margin="5,15">
<DataGrid.Columns>
<DataGridTextColumn Header="Employee ID"
Binding="{Binding EmployeeID}"/>
<DataGridTextColumn Header="Employee Name"
Binding="{Binding EmployeeName}"/>
<DataGridTextColumn Header="EmployeeDepartment"
Binding="{Binding EmployeeDepartment}"/>
<DataGridTextColumn Header="Employee Designation"
Binding="{Binding EmployeeDesignation}"/>
<DataGridTextColumn Header="Contact Number"
Binding="{Binding EmployeeContactNo}"/>
<DataGridTextColumn Header="Employee Location"
Binding="{Binding EmployeeLocation}"/>
</DataGrid.Columns>
</DataGrid>
<Grid Grid.Row="1" Background="LightBlue" Margin="6,30">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="160"/>
</Grid.ColumnDefinitions>
<Label Name="lbEmpID" Content="Employee ID"
Grid.Row="0" Grid.Column="0" Height="30"/>
<TextBox Name="tbEmpID" Height="30"
Grid.Row="0" Grid.Column="1" />
<Label Name="lbEmpName" Height="30"
Content="Employee Name" Grid.Row="0" Grid.Column="2"/>
<TextBox Name="tbEmpName" Height="30"
Grid.Row="0" Grid.Column="3"
Text="{Binding EmployeeName, UpdateSourceTrigger=PropertyChanged}"/>
<Label Name="lbEmpDepartment" Height="30"
Content="Employee Department" Grid.Row="1" Grid.Column="0"/>
<TextBox Name="tbEmpDepartment" Height="30"
Grid.Row="1" Grid.Column="1"/>
<Label Name="lbEmpDesignation" Height="30"
Content="Employee Designation" Grid.Row="1" Grid.Column="2"/>
<TextBox Name="tbEmpDesignation" Height="30"
Grid.Row="1" Grid.Column="3"/>
<Label Name="lbEmpContactNo" Height="30"
Content="Contact Number" Grid.Row="2" Grid.Column="0"/>
<TextBox Name="tbEmpContactNo" Height="30"
Grid.Row="2" Grid.Column="1"/>
<Label Name="lbEmpLocation" Height="30"
Content="Employee Location" Grid.Row="2" Grid.Column="2"/>
<TextBox Name="tbEmpLocation" Height="30"
Grid.Row="2" Grid.Column="3"/>
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="2"
Height="40" Width="250">
<Button Name="btnSubmit" Content="Submit"
Click="btnSubmit_Click" Width="100" Height="30" FontSize="14"/>
<Button Name="btnClearGrid" Content="ClearGrid"
Click="btnClearGrid_Click" Width="100" Height="30" Margin="20,0,0,0"/>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal">
<Label Content="You have given the Employee name as.."
FontSize="14" Foreground="Green"
FontWeight="Bold" Height="30" Margin="10,0,0,0"/>
<TextBlock Name="tbText" Text="{Binding EmployeeName}"
FontSize="16" FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" VerticalAlignment="Center"
Height="50" Width="250" Padding="15"/>
</StackPanel>
</Grid>
</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. It's 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. That plays a major role here...
Let's 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:
public MainWindow()
{
this.DataContext = new EmployeeViewModel();
InitializeComponent();
}
After entering the data in the textbox
es 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
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;
namespace Adding_To_DataGrid
{
public partial class MainWindow : Window
{
public MainWindow()
{
this.DataContext = new EmployeeViewModel();
InitializeComponent();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
AddToGrid();
}
public void AddToGrid()
{
List<EmployeeViewModel> empCollection = new List<EmployeeViewModel>();
empCollection.Add(new EmployeeViewModel()
{
EmployeeID = Convert.ToInt32(tbEmpID.Text),
EmployeeName = tbEmpName.Text,
EmployeeDepartment = tbEmpDepartment.Text,
EmployeeDesignation = tbEmpDesignation.Text,
EmployeeContactNo = tbEmpContactNo.Text,
EmployeeLocation = tbEmpLocation.Text
});
dgDataGrid.Items.Add(empCollection);
ClearFields();
}
public void ClearFields()
{
tbEmpID.Text = "";
tbEmpName.Text = "";
tbEmpDepartment.Text = "";
tbEmpDesignation.Text = "";
tbEmpContactNo.Text = "";
tbEmpLocation.Text = "";
}
private void btnClearGrid_Click(object sender, RoutedEventArgs e)
{
dgDataGrid.Items.Clear();
}
}
}
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 line below.
private void btnExplicit_Click(object sender, RoutedEventArgs e)
{
BindingExpression obj = tbEmpName.GetBindingExpression(TextBox.TextProperty);
obj.UpdateSource();
}
Now in this article, I hope you understand how simple binding works and how the text is updated by using UpdateSourceTrigger
as PropertyChanged
. Please rate this simple article if you likeā¦
Please download the full sample from the link at the top of the article.
Happy coding!!!