The problem of the Windows Phone 7 ApplicationBar and not (yet) updated Bindings

As a MVVM enthusiast I’m trying to use MVVM as much as possible, but not for things that are almost impossible to do with MVVM. But simple things, like a TextBox Text property is always bound to a ViewModel’s property. That’s something that works very well…until you start having ApplicationBar buttons and menu items.

A lot of people already know that the ApplicationBar is something special, it’s not just a control like other stuff in your application. When clicking a button on the ApplicationBar the Binding is not yet updated. This is basically because the focus which is on the TextBox for example won’t be changed when clicking ApplicationBar buttons. This is different compared to normal buttons that you put somewhere on your page.

The Solution?

I’ve read different solutions on the web. For example, force focus on a different control by calling the Focus method on a Control. While this is working, I found a technically nicer solution. By getting the Binding of the current focused control and updating that binding.

I wrote a small helper class that implements this Binding updating.

public static class ApplicationBarHelper
{
    public static void UpdateBindingOnFocussedControl()
    {
        object focusedElement = FocusManager.GetFocusedElement();
        if (focusedElement != null && focusedElement is TextBox)
        {
            var binding = (focusedElement as TextBox).GetBindingExpression(TextBox.TextProperty);
            if (binding != null)
                binding.UpdateSource();
        }
    } 
}

The first thing you do in the Event handlers for the ApplicationBar Click events is call.

ApplicationBarHelper.UpdateBindingOnFocussedControl();

What about the BindableApplicationBar?

A lot of use MVVM enthusiasts are using the BindableApplicationBar that’s part of the Phone7.Fx library. Can we use this in combination with the BindableApplicationBar? Yes we can, actually the best way would be to have this integrated with the BindableApplicationBar itself. I have just downloaded the source and manipulated two methods in two classes.

public class BindableApplicationBarIconButton : FrameworkElement, IApplicationBarIconButton
{
    // Other code that hasn't been changed in this class.

    void ApplicationBarIconButtonClick(object sender, EventArgs e)
    {
        ApplicationBarHelper.UpdateBindingOnFocussedControl();
        if (Command != null && CommandParameter != null)
            Command.Execute(CommandParameter);
        else if (Command != null)
            Command.Execute(CommandParameterValue);
        if (Click != null)
            Click(this, e);
    }
}

public class BindableApplicationBarMenuItem : FrameworkElement, IApplicationBarMenuItem
{
    // Other code that hasn't been changed in this class.

    private void ApplicationBarMenuItemClick(object sender, EventArgs e)
    {
        ApplicationBarHelper.UpdateBindingOnFocussedControl();
        if (Command != null && CommandParameter != null)
            Command.Execute(CommandParameter);
        else if (Command != null)
            Command.Execute(CommandParameterValue);
        if (Click != null)
            Click(this, e);
    }
}
Gravatar