Custom Silverlight TextBox control that immediately updates DataBound Text property in TwoWay binding

Standard Silverlight TextBox control is very useful but has one strange behavior: if you use TwoWay data binding and bind some property to controls Text property, when users type text into the control, this change is not propagated to the bound property until the control loses its focus.

This can be very annoying if you have MVVM application and you have some kind of real-time filter that needs to update some data as-you-type.

Problem is that TextBox control does not call BindingExpression.UpdateSource when its Text property is changed so we have to do that manually in order to fix this issue.

To fix this once and for all I have created simple custom control ImmediateTextBox that inherits the standard TextBox and just calls BindingExpression.UpdateSource for TextBox.TextProperty whenever text is changed.

Here is all the code that is in our custom control:

using System.Windows.Controls;

namespace ImmediateDataBindingTextBox
{
    public class ImmediateTextBox : TextBox
    {
        public ImmediateTextBox()
        {
            this.Loaded += ImmediateTextBox_Loaded;
        }

        void ImmediateTextBox_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            this.TextChanged += ImmediateTextBox_TextChanged;
        }

        void ImmediateTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            var tb = sender as TextBox;
            if (tb != null)
            {
                var be = tb.GetBindingExpression(TextBox.TextProperty);
                if (be != null)
                {
                 be.UpdateSource();
                }
            }
        }
    }
}

And here is the demo application that shows this in action.
In sample app you have standard TextBox and our custom ImmediateTextBox that are both bound to some property in ViewModel using TwoWay binding.

Below is TextBlock also bound to same property to show the current value of the property.

If you type text into standard TextBox the text in TextBlock will not be updated until TextBox loses its focus and if you type text into our custom control you will see the changes propagated to the underlying property immediately.

If you want to use this control you can download sample Visual Studio 2010 Solution

Hope someone can find this useful when doing MVVM style applications where you cannot just reach for the code in code-behind to fix problems like this :)

12 thoughts on “Custom Silverlight TextBox control that immediately updates DataBound Text property in TwoWay binding

  1. David Padbury

    Implementing this as a Blend Behavior would be pretty much identical to what you’ve got and it’s a technique that I frequently use. What I find a little painful with the Blend Behaviors is that we’re unable to apply them in a Style making the XAML for a form with many TextBoxes a bit of a mess. The method presented here would not have the same problem.

    1. roboblob Post author

      Yes Behaviors are anyway meant to be created so they can be reused on different Controls and this would hardly be reusable on different controls so it seems that custom control is a better fit after all…

  2. Mike stokes

    Cool! The other place the default behavior causes a problem is when users enter info in a textbox then close the user control that hosts it… The lost focus isn’t captured and the data is lost in an mvvm model.

    This solves that nicely :)

    1. roboblob Post author

      yes this is known problem, im surprised that Microsoft did not fix this ‘feature’ already.
      Anyway this simple control solves it elegantly so everyone can use it…

      Cheers!

  3. Maria

    Hello
    Uf, this solution is exactly what I was looking for, but I cannot get it to work. I have inserted the class, and added the xmlns in my xaml… but it doesn’t recognize the type, when I want to insert the ImmediateTextBox. Is there anything else that needs to be done, before this should work?
    Thank you!

  4. Richard Reukema

    I found another solution thanks to Laurent of MVVM toolkit – he uses the KeyUp event, which fires each time the key is lifted. I saw this in one of his examples – sorry can’t remember which one!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>