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
- <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 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
- 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 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
- <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. 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
- public MainWindow()
- {
- this.DataContext = new EmployeeViewModel();
- InitializeComponent();
- }
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
- 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 lie 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 updated by using UpdateSourceTrigger as PropertyChanged. Please rate this simple Article if you like…
Please download the full Sample .
Happy Coding !!!