Introduction
Don't you miss the "UpdateSourceTrigger=PropertyChanged
" on a Binding
expression on Silverlight? Well, me too, and since I don't like the idea of having a hidden control to change focus on every TextChange
of my TextBox
es, I tried to make a more elegant solution for the problem.
Background
In both WPF and Silverlight, when we create a BindingExpression
, you can define a UpdateSourceTrigger
property of the Binding
. But, there is a huge difference between them, Silverlight has only the Default
mode (LostFocus
) and Explicit
, so we are missing PropertyChanged
that in some cases makes our life way easier.
Using the Code
The code is fairly simple. It is only one AttachedProperty
that will handle the TextChanged
for you and will update the BindingSource
if the BindingExpression
of the TextProperty
exists.
This was only implemented in the TextBox
because there is no need to change the other input controls over the fact that LostFocus
works perfect for them (like ComboBox
es, CheckBox
es, RadioButton
s).
So, we define an AttachedProperty
that shouldn't be a problem to any Silverlight developer:
public static bool GetUpdateOnPropertyChanged(DependencyObject obj)
{
return (bool)obj.GetValue(UpdateOnPropertyChangedProperty);
}
public static void SetUpdateOnPropertyChanged(DependencyObject obj, bool value)
{
obj.SetValue(UpdateOnPropertyChangedProperty, value);
}
public static readonly DependencyProperty UpdateOnPropertyChangedProperty =
DependencyProperty.RegisterAttached(
"UpdateOnPropertyChanged",
typeof(bool),
typeof(UpdateSourceManager),
new PropertyMetadata(
new PropertyChangedCallback(
UpdateOnPropertyChangedPropertyCallback)));
Then we define the UpdateOnPropertyChangedPropertyCallback
:
static void UpdateOnPropertyChangedPropertyCallback(
DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (sender is TextBox)
{
TextBox txt = sender as TextBox;
txt.TextChanged += new TextChangedEventHandler(txt_TextChanged);
}
}
static void txt_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox txt = sender as TextBox;
var bindingExpression = txt.GetBindingExpression(TextBox.TextProperty);
if (bindingExpression != null)
{
bindingExpression.UpdateSource();
}
}
Then, for using this, just add to your UserControl
the proper XML namespace like:
<UserControl x:class="UpdateSourceTrigger.MainPage"
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:UpdateSourceTrigger"
mc:ignorable="d">
And finally, add the Attached Property to the TextBox
as follows:
<TextBox
Text="{Binding Context.FirstName, Mode=TwoWay}"
Grid.Column="1"
Grid.Row="0"
Margin="5"
local:UpdateSourceManager.UpdateOnPropertyChanged="True"
/>
The End
Hope this can make things easier to you, as it did to me.