Introduction
We all know WPF is UI designing framework that has an enhanced way of displaying and manipulating data.
The concept is known as Data Binding, we can get data from 'N' number sources such as API, entity framework any other ORM tools, or static data.
Here, data binding is a layer between UI elements & data.
It shows dynamic data changes: meaning if the data source is updated so is your UI.
In WPF, there are 4 types of binding
- One-Way Binding
- Two-Way Binding
- One-Way To Source
- One_Time Binding
- Default
Let's learn them one by one.
One-Way Data-binding
One way allows changes from the source-destination meaning, data can only flow from one direction.
Create a WPF app with the following controls.
A grid with 2 labels & 2 textboxes in XAML might look something like this.
<Window x:Class="A.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:A"
mc:Ignorable="d"
Title="MainWindow" Height="150" Width="500">
<Window.Resources>
<Thickness x:Key="MarginTop">0 5 0 0</Thickness>
</Window.Resources>
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="Source" Margin="0 30 0 0"/>
<TextBox x:Name="SourceTextBox" Width="150" Height="25" Margin="0 30 0 0" Grid.Column="1"/>
<Label Content="Destination" Margin="0 5 0 0" Grid.Row="1"/>
<TextBox x:Name="DestinationTextBox" Text="{Binding ElementName=SourceTextBox, Path=Text, Mode=OneWay}"
Margin="{StaticResource MarginTop}" Width="150" Height="25" Grid.Column="1" Grid.Row="1"/>
</Grid>
</Window>
The first textbox will take input and the second textbox will display the same text that you entered in the first textbox.
the second textbox will update itself with every single keystroke you entered in the first textbox.
As you can see in the second textbox which is named DestinationTextBox we have Text Property: which is bound with a first textbox(SourceTextBox) & has a set
Mode = OneWay
This is how the output would look like: Note: watch the complete gif to understand One-way binding's behavior.
Explanation
As you can see, whatever I type in the source textbox it gets reflected in the destination textbox. But it doesn't work vice-versa. because our destination textbox has one-way binding. it will not let the source know if it has updated itself.
Two-Way Binding
Data can flow bi-directionally, from source to destination and from destination to source.
Keep the same example, but make changes in DestinationTextBox as follows.
<TextBox x:Name="DestinationTextBox"
Text="{Binding ElementName=SourceTextBox, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="{StaticResource MarginTop}"
Width="150"
Height="25"
Grid.Column="1"
Grid.Row="1"/>
This is how the output would be...
Again, watch the complete gif.
Explanation
Now we have Mode = TwoWay in the Destination textbox. Also, see we have UpdateSourceTrigger=PropertyChanged which updates the source textbox with every keystroke.
One-Way To Source
Now we have seen data flow from source to destination & from destination to source. now, 3rd mode is in the middle of these 2 modes. what if I wanted to flow data from destination to source & didn't want data to be flown back from the source? i.e. data flow in one way to the source.
Just change Mode = OneWayToSource in XAML as follows.
<TextBox x:Name="DestinationTextBox"
Text="{Binding ElementName=SourceTextBox, Path=Text, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
Margin="{StaticResource MarginTop}"
Width="150"
Height="25"
Grid.Column="1"
Grid.Row="1"/>
This is the output
Explanation
As you can see, we can update the source from the destination but the source is unable to do the same!
Hence, OneWayToSource.
One_Time Binding
Data flows from any direction but only one time. Data is bound when control is created or when the data context is changed. after that, any changes to either the bound property or the data source are not transmitted.
We will assign some text to the constructor to understand its behavior.
Update MainWindow.xaml.c is as follows.
using System.Windows;
namespace A
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
SourceTextBox.Text = "One Time Mode";
DestinationTextBox.Text = SourceTextBox.Text;
}
}
}
Make 1 line change in XAML: Mode=OneTime in DestinationTextBox.
<TextBox x:Name="DestinationTextBox"
Text="{Binding ElementName=SourceTextBox, Path=Text, Mode=OneTime, UpdateSourceTrigger=PropertyChanged}"
Margin="{StaticResource MarginTop}"
Width="150"
Height="25"
Grid.Column="1"
Grid.Row="1"/>
See the output.
Explanation
Data is loaded only once when the constructor is loaded, After that no changes are reflected in the destination if source data is changed. Hence OneTime.
Default Data-binding
It just defines which is the default binding mode for the control's property. In WPF different controls have different default data-binding modes.
For example, TextBlock's Text property has one-way as the default binding mode but Textbox's Text property has a two-way binding mode.
This is because the control behaviors differ from one another.
As text block is read-only control, the user can't make changes by clicking on it, that's why it has one-way as default.
Users can make changes in the textbox so it has two ways as the default binding mode.
I hope this article has cleared the confusion you might had about different binding modes in WPF.
Feel free to apply them in your project to understand their behavior.
Thank you for visiting this article.
If you have any doubt, you can contact me @
Happy Coding!