Introduction
In this article I want to show you the concept of updating the source of a binding in WPF and Silverlight. As you may know,
when we use TwoWay
as the mode of our binding, any change that takes place in the target of the binding affects the value of the source. Please note that
this only happens when we use TwoWay
binding, not OneWay
, which is the default mode, or
OneTime
.
Now, the question is when to update the source with the changes that has taken place in the target. Well, there are actually three approaches:
- Default: Varies from control to control. For
TextBox
, for example, it means when the
LostFocus
event of the target of the binding occurs.
PropertyChanged
: Means that when a change occurs in the target, the source is updated immediately. For example, as you type characters in a
TextBox
which is the target of a binding, the source is updated, too. This means that the
Text
property of the
TextBox
changes as you type characters.
- Explicit: When
UpdateSourceTrigger
is set to Explicit
, the source doesn’t get updated until you do this explicitly in
the code-behind.
For all of these approaches I have written some code to help you better understand them. We begin with
the default approach. Look at the following piece of code:
<Border BorderThickness="2" Margin="0 20 0 0" BorderBrush="Brown" CornerRadius="5">
<StackPanel>
<TextBox x:Name="textInput2" Margin="5" />
<TextBox x:Name="txtOutput2" Margin="5"
Text="{Binding Text,
ElementName=textInput2,
UpdateSourceTrigger=Default,
Mode=TwoWay}"/>
</StackPanel>
</Border>
Here, there is a Border
element, within which a StackPanel
which contains two TextBox
es. The
Text
property of the second TextBox
is bound
to the Text
property of the first TextBox
. Actually, this is the same code in all of our examples.
The Mode
of the binding is set to TwoWay
because we want to update the source whenever a change occurs in the target. And finally, the
UpdateSourceTrigger
property of the binding is set to Default
. This means that
when the second TextBox
, which is the target of the binding, loses
focus (or the LostFocus
event fires), the string in the Text
property of the first
TextBox
,
which is the source of the binding, is updated.
Our second example deals with setting the UpdateSourceTrigger
to PropertyChanged
.
<Border BorderThickness="2" BorderBrush="Brown" CornerRadius="5">
<StackPanel>
<TextBox x:Name="textInput1" Margin="5" />
<TextBox x:Name="txtOutput1" Margin="5"
Text="{Binding Text,
ElementName=textInput1,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}"/>
</StackPanel>
</Border>
The only thing that is different in this piece of code compared to the first one is that the
UpdateSourceTrigger
is set to
PropertyChanged
. As the name implies, this means that whenever there is a change in the
Text
property of the second TextBox
, the Text
property of the
first TextBox
gets updated immediately.
And finally our last example is about setting the UpdateSourceTrigger
property to
Explicit
.
<Border BorderThickness="2" Margin="0 20 0 0" BorderBrush="Brown" CornerRadius="5">
<StackPanel>
<TextBox x:Name="textInput3" Margin="5" />
<TextBox x:Name="txtOutput3" Margin="5"
Text="{Binding Text,
ElementName=textInput3,
UpdateSourceTrigger=Explicit,
Mode=TwoWay}"/>
<Button Content="Save" Click="Button_Click"/>
</StackPanel>
</Border>
The thing that differs in this piece of code is that the UpdateSourceTrigger
is set to
Explicit
. As we said earlier, this means that the
updating process doesn’t take place unless you do it explicitly. The Button
which is declared after the second
TextBox
is responsible for doing this. As
you may have noticed, there is an EventHandler for its Click
event, and the following lines of code
are written in that EventHandler.
private void Button_Click(object sender, RoutedEventArgs e)
{
BindingExpression be = txtOutput3.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
}
An instance of the BindingExpression
class is declared named
be
. After that, the binding expression for the
Text
property of the txtOutput3
is
grabbed and put in that instance. And finally, the UpdateSource
method of be
is called which updates the source of the binding explicitly.