An attached behavior for WPF TextBoxes to force instant binding

Update – Apr 9, 2010

You do not need to do all this – instead you just need to set UpdateSourceTrigger on the Binding to PropertyChanged. I’ve made an updated blog entry on this here : Correction for the instant binding attached behavior for WPF TextBoxes

Original entry follows for posterity

The default behavior for a TextBox is to invoke data binding when the TextBox loses focus. Normally this is fine since people do have to hit an OK button somewhere, but there are times when you’d prefer that databinding occurs as you type into the TextBox. I wrote an attached property for the TextBox which invokes data binding as you type into it, and not when the text box goes out of focus. Here’s how you would use it.

<TextBox Height="23"
  nsmvvm:TextInstantBindingBehavior.EnableInstantBinding="True"
  Text="{Binding EnteredName}" HorizontalAlignment="Left"
  Margin="144,64,0,0" Name="textBoxName"
  VerticalAlignment="Top" Width="152" />

Here’s the code for the attached property.

public class TextInstantBindingBehavior
{
    public static DependencyProperty EnableInstantBindingProperty =
      DependencyProperty.RegisterAttached(
          "EnableInstantBinding",
          typeof(bool), typeof(TextInstantBindingBehavior),
          new FrameworkPropertyMetadata(
              new PropertyChangedCallback(EnableInstantBindingChanged)));

    public static void SetEnableInstantBinding(TextBox target, bool value)
    {
        target.SetValue(
          TextInstantBindingBehavior.EnableInstantBindingProperty, value);
    }

    public static bool GetEnableInstantBinding(TextBox target)
    {
        return (bool)target.GetValue(EnableInstantBindingProperty);
    }

    private static void EnableInstantBindingChanged(
        DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        TextBox element = target as TextBox;

        if (element != null)
        {
            if (e.NewValue != null && (bool)e.NewValue)
            {
                element.TextChanged += Element_TextChanged;
            }
            else
            {
                element.TextChanged -= Element_TextChanged;
            }
        }
    }

    static void Element_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = (TextBox)sender;

        if (GetEnableInstantBinding(textBox))
        {
            BindingExpression bindingExpression =
              textBox.GetBindingExpression(TextBox.TextProperty);

            if (bindingExpression != null)
            {
                bindingExpression.UpdateSource();
            }
        }
    }
}
Advertisements

3 thoughts on “An attached behavior for WPF TextBoxes to force instant binding

  1. Thank you Ed. Someone else pointed it out to me today – for some reason I did not get your comment notification. I have added a new blog entry pointing out this mistake, and am in the process of updating this entry to point to the correction.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s