If you have TextBox controls in your app and you’re binding to the Text property (two-way mode), you should by now have noticed that the binding source isn’t updated when you tap an icon or menu item in the app bar!
The first thing you need to know in order to understand why this is happening, is that the TextBox control only updates the Text binding source when the control looses focus.
Second reason is that the ApplicationBar control can’t get focus, nor can it’s ApplicationBarIconButton or ApplicationBarMenuItem controls, so when you tap on them, the click event will be invoked without the TextBox control ever loosing focus!
To fix this behavior we need to force an update on the binding source when the click event get’s invoked, and here’s some code on how to achieve this:
var focusedElement = FocusManager.GetFocusedElement();
var focusedTextBox = focusedElement as TextBox;
if (focusedTextBox != null)
{
var binding = focusedTextBox.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
We start by using FocusManager.GetFocusedElement method to get the current focused element. Then we check if that is a TextBox control, and if so, force it to update the Text property binding source!
The same problem will happen with PasswordBox, so it’s best just to handle both situations and encapsulate this in a reusable method:
public static void FocusedTextBoxUpdateSource()
{
var focusedElement = FocusManager.GetFocusedElement();
var focusedTextBox = focusedElement as TextBox;
if (focusedTextBox != null)
{
var binding = focusedTextBox.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
else
{
var focusedPasswordBox = focusedElement as PasswordBox;
if (focusedPasswordBox != null)
{
var binding = focusedPasswordBox.GetBindingExpression(PasswordBox.PasswordProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
}
}
All you now need is to call the FocusedTextBoxUpdateSource
method in the start of the app bar item control click event handler so that it will update the binding source before the rest of the code runs!
You can find this problem fixed on some toolkits and frameworks, like Caliburn.Micro and my own Cimbalino Windows Phone Toolkit ApplicationBarBehavior.
Another way to fix this would be by updating the binding source on text changed rather than when it looses focus, and for that you can use the TextBinding helper from Coding4Fun Toolkit for Windows Phone.