Bind TextBox on Enter-key press
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).
This is how I solved this problem. I created a special event handler that went into the code behind:
private void TextBox_KeyEnterUpdate(object sender, KeyEventArgs e){ if (e.Key == Key.Enter) { TextBox tBox = (TextBox)sender; DependencyProperty prop = TextBox.TextProperty; BindingExpression binding = BindingOperations.GetBindingExpression(tBox, prop); if (binding != null) { binding.UpdateSource(); } }}
Then I just added this as a KeyUp event handler in the XAML:
<TextBox Text="{Binding TextValue1}" KeyUp="TextBox_KeyEnterUpdate" /><TextBox Text="{Binding TextValue2}" KeyUp="TextBox_KeyEnterUpdate" />
The event handler uses its sender
reference to cause it's own binding to get updated. Since the event handler is self-contained then it should work in a complex DataTemplate. This one event handler can now be added to all the textboxes that need this feature.
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.