using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace Controls { /// /// /// Represents a TextBox that can update the binding on enter. /// public class TextBoxEx : TextBox { /// /// Identifies the dependency property. /// public static readonly DependencyProperty MoveFocusOnEnterProperty = DependencyProperty.Register( "MoveFocusOnEnter", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty UpdateBindingOnEnterProperty = DependencyProperty.Register( "UpdateBindingOnEnter", typeof(bool), typeof(TextBoxEx), new UIPropertyMetadata(true)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty ScrollToHomeOnFocusProperty = DependencyProperty.Register("ScrollToHomeOnFocus", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(true)); /// /// Identifies the dependency property. /// public static readonly DependencyProperty SelectAllOnFocusProperty = DependencyProperty.Register("SelectAllOnFocus", typeof(bool), typeof(TextBoxEx), new PropertyMetadata(true)); /// /// /// Initializes a new instance of the class. /// public TextBoxEx() { GotKeyboardFocus += HandleGotKeyboardFocus; } /// /// Gets or sets a value indicating whether to select all on focus. /// /// /// true if all should be selected; otherwise, false. /// public bool SelectAllOnFocus { get => (bool)GetValue(SelectAllOnFocusProperty); set => SetValue(SelectAllOnFocusProperty, value); } /// /// Gets or sets a value indicating whether to scroll to home on focus. /// /// /// true if scroll is enabled; otherwise, false. /// public bool ScrollToHomeOnFocus { get => (bool)GetValue(ScrollToHomeOnFocusProperty); set => SetValue(ScrollToHomeOnFocusProperty, value); } /// /// Gets or sets a value indicating whether MoveFocusOnEnter. /// public bool MoveFocusOnEnter { get => (bool)GetValue(MoveFocusOnEnterProperty); set => SetValue(MoveFocusOnEnterProperty, value); } /// /// Gets or sets a value indicating whether UpdateBindingOnEnter. /// public bool UpdateBindingOnEnter { get => (bool)GetValue(UpdateBindingOnEnterProperty); set => SetValue(UpdateBindingOnEnterProperty, value); } /// protected override void OnPreviewKeyDown(KeyEventArgs e) { base.OnPreviewKeyDown(e); switch (e.Key) { case Key.Enter: if (!AcceptsReturn) { if (UpdateBindingOnEnter) { // get the binding to the Text property var bindingExpression = GetBindingExpression(TextProperty); // update the source (do not update the target) bindingExpression?.UpdateSource(); } if (MoveFocusOnEnter) { // Move focus to next element // http://madprops.org/blog/enter-to-tab-in-wpf/ if (e.OriginalSource is UIElement uiElement) { var shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; uiElement.MoveFocus(new TraversalRequest(shift ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next)); } } e.Handled = true; } break; case Key.Escape: Undo(); SelectAll(); e.Handled = true; break; } } /// protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnPreviewMouseLeftButtonDown(e); if (!IsKeyboardFocusWithin) { SelectAll(); Focus(); e.Handled = true; } } /// /// Handles the got keyboard focus event. /// /// The sender. /// The instance containing the event data. private void HandleGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { if (SelectAllOnFocus) { SelectAll(); } if (ScrollToHomeOnFocus) { ScrollToHome(); } e.Handled = true; } } }