Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Keeping It Focused

0.00/5 (No votes)
9 Jul 2012 1  
The solution to a problem that was posted on CodeProject

Well, it’s been a while since I’ve blogged, as I’ve been a busy little bee working on CodeStash. I feel guilty about this, so I’d like to take the chance to pass on the solution to a problem that was posted on CodeProject today. The scenario goes like this:

You have a ViewModel with some text that you want to be updated, and you do all the usual binding work with some TextBox elements. The thing is, you want to update your ViewModel properties when the TextBox loses focus. OK, so that’s easily achieved – in fact, it’s the default behaviour of the TextBox. However, you have a button with IsDefault set on it, so pressing Enter in the TextBox triggers the button click – but as the TextBox hasn’t lost focus, the property you are binding to doesn’t get updated. This is, of course, a problem. Fortunately, there’s an easy little trick that you can deploy to update the property, and it’s easily achieved using an attached behavior.

All you need to do is associate the behaviour to the Button you have set the IsDefault property on, and Bob is your mothers brother, the Text property updates. So, what does this behavior look like:

C#
using System.Windows.Interactivity;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using System.Windows.Data;
/// <summary>
/// Associate this behaviour with the button that you mark as IsDefault
/// to trigger the ViewModel update when the user clicks enter in a textbox
/// and the property doesn't update because the update source is set to
/// lost focus.
/// </summary>
public class DefaultButtonUpdateTextBoxBindingBehavior : Behavior<Button>
{
    /// <summary>
    /// Hook into the button click event.
    /// </summary>
    protected override void OnAttached()
    {
        AssociatedObject.Click += AssociatedObject_Click;
        base.OnAttached();
    }

    /// <summary>
    /// Unhook the button click event.
    /// </summary>
    protected override void OnDetaching()
    {
        AssociatedObject.Click -= AssociatedObject_Click;
    }

    /// <summary>
    /// The click event handler.
    /// </summary>
    void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        // Get the element with the keyboard focus
        FrameworkElement el = Keyboard.FocusedElement as FrameworkElement;
        if (el != null && el is TextBox)
        {
            // Get the binding expression associated with the text property
            // for this element.
            BindingExpression expression = el.GetBindingExpression(TextBox.TextProperty);
            if (expression != null)
            {
                // Now, trigger the update.
                expression.UpdateSource();
            }
        }
    }
}

As you can see, there’s not that much code needed. Basically, we get the element that has focus, and retrieve the binding expression associated with it. Once you get the binding expression, we trigger the update.

I’ve copied this behaviour into CodeStash – the handy repository that I will be putting future snippets in for your delectation.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here