Bind TextBox on Enter-key press


Question

The default databinding on TextBox is TwoWay and it commits the text to the property only when TextBox lost its focus.

Is there any easy XAML way to make the databinding happen when I press the Enter key on the TextBox?. I know it is pretty easy to do in the code behind, but imagine if this TextBox is inside some complex DataTemplate.

1
102
6/16/2016 12:01:14 AM

Accepted Answer

You can make yourself a pure XAML approach by creating an attached behaviour.

Something like this:

public static class InputBindingsManager
{

    public static readonly DependencyProperty UpdatePropertySourceWhenEnterPressedProperty = DependencyProperty.RegisterAttached(
            "UpdatePropertySourceWhenEnterPressed", typeof(DependencyProperty), typeof(InputBindingsManager), new PropertyMetadata(null, OnUpdatePropertySourceWhenEnterPressedPropertyChanged));

    static InputBindingsManager()
    {

    }

    public static void SetUpdatePropertySourceWhenEnterPressed(DependencyObject dp, DependencyProperty value)
    {
        dp.SetValue(UpdatePropertySourceWhenEnterPressedProperty, value);
    }

    public static DependencyProperty GetUpdatePropertySourceWhenEnterPressed(DependencyObject dp)
    {
        return (DependencyProperty)dp.GetValue(UpdatePropertySourceWhenEnterPressedProperty);
    }

    private static void OnUpdatePropertySourceWhenEnterPressedPropertyChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        UIElement element = dp as UIElement;

        if (element == null)
        {
            return;
        }

        if (e.OldValue != null)
        {
            element.PreviewKeyDown -= HandlePreviewKeyDown;
        }

        if (e.NewValue != null)
        {
            element.PreviewKeyDown += new KeyEventHandler(HandlePreviewKeyDown);
        }
    }

    static void HandlePreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            DoUpdateSource(e.Source);
        }
    }

    static void DoUpdateSource(object source)
    {
        DependencyProperty property =
            GetUpdatePropertySourceWhenEnterPressed(source as DependencyObject);

        if (property == null)
        {
            return;
        }

        UIElement elt = source as UIElement;

        if (elt == null)
        {
            return;
        }

        BindingExpression binding = BindingOperations.GetBindingExpression(elt, property);

        if (binding != null)
        {
            binding.UpdateSource();
        }
    }
}

Then in your XAML you set the InputBindingsManager.UpdatePropertySourceWhenEnterPressedProperty property to the one you want updating when the Enter key is pressed. Like this

<TextBox Name="itemNameTextBox"
         Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}"
         b:InputBindingsManager.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>

(You just need to make sure to include an xmlns clr-namespace reference for "b" in the root element of your XAML file pointing to which ever namespace you put the InputBindingsManager in).

129
9/10/2015 10:59:51 AM

I don't believe that there's any "pure XAML" way to do what you're describing. You can set up a binding so that it updates whenever the text in a TextBox changes (rather than when the TextBox loses focus) by setting the UpdateSourceTrigger property, like this:

<TextBox Name="itemNameTextBox"
    Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}" />

If you set UpdateSourceTrigger to "Explicit" and then handled the TextBox's PreviewKeyDown event (looking for the Enter key) then you could achieve what you want, but it would require code-behind. Perhaps some sort of attached property (similar to my EnterKeyTraversal property) woudld work for you.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon