16

I created some textboxes and I want user to enter decimal values into them. In every application I have ever used, when I type something into the textbox and hit enter, the value is accepted and textbox lose focus. How can I do it in my app? I know it should be relatively easy to do it with a key event, but maybe there is a command or something. I searched the stackoverflow but I only found questions about how to keep focus after hitting enter...

Dess
  • 405
  • 3
  • 9
  • 22
  • Usually you use tab to lose focus, you can set up buttons as confirm button, which will be toggled by enter. But simply losing focus on a textbox from hitting enter sounds strange to me, you'll probably need to code it yourself in key events as you suggested. – Kevin DiTraglia May 12 '14 at 15:38
  • 1
    Strange?:P so what about when you enter www address in webbrowser? There's no button to confirm, you simply hit enter. – Dess May 12 '14 at 15:42
  • what's your process flow after hit enter, do you need to hit enter for each individual textboxes? – Bolu May 12 '14 at 15:42
  • 1
    Right, this is the button taking enter as confirm as I suggested, which would have the side-effect of de-selecting the box. To do this just set your confirm button to have the `IsDefault` property to true. – Kevin DiTraglia May 12 '14 at 15:44
  • 1
    I have 4 boxes in a row, I can go through them with tab at first(but what if I want to change value later in only one textbox, tab wouldn't be best choice), but my last textbox is binded to slider, when I enter the value and hit enter I want automatically change the value in slider. I can't do that now, because I need to lose focus by clicking another component for the value to be accepted. – Dess May 12 '14 at 15:47
  • you can update your slider without lose focus on your textbox by setting textbox's `UpdateSourceTrigger` to `PropertyChanged` – Bolu May 14 '14 at 08:51
  • 2
    I'm with the OP. Pressing Enter on a box is a perfectly intuitive thing. This isn't about pure logic, but what the intuition of the common user does. And most of them WILL press enter, until in some occasions. – j riv Jun 04 '15 at 20:02

1 Answers1

24

You can also create a generic behavior which can be easily applied to any textbox within your application. Here is a sample behavior class:-

public class TextBoxEnterKeyUpdateBehavior : Behavior<TextBox>
{        
    protected override void OnAttached()
    {
        if (this.AssociatedObject != null)
        {
            base.OnAttached();
            this.AssociatedObject.KeyDown += AssociatedObject_KeyDown;
        }
    }

    protected override void OnDetaching()
    {
        if (this.AssociatedObject != null)
        {
            this.AssociatedObject.KeyDown -= AssociatedObject_KeyDown;
            base.OnDetaching();
        }
    }

    private void AssociatedObject_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox != null)
        {
            if (e.Key == Key.Return)
            {
                if (e.Key == Key.Enter)
                {
                    textBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                }
            }
        }
    }
}

To use this class in your xaml, just include it in textbox behaviors collection like this :-

<TextBox>
    <i:Interaction.Behaviors>
           <TextBoxEnterKeyUpdateBehavior />
    </i:Interaction.Behaviors>
</TextBox>

Here "i" refers to System.Windows.Interactivity namespace.

Precog
  • 354
  • 3
  • 13
  • 1
    Note that the proper import of the `i` namespace in XAML is `xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"` – cod3monk3y Aug 10 '14 at 18:28
  • Can I add this in the resource file? SO that I don't have to write it again and again, – fhnaseer Sep 08 '14 at 10:37
  • 2
    To be honest, I'm suspicious with the huge amount of points such suggestions get just because they are more "XAML-y". The other answer is a single small function and a line for each key. This one needs a huge spam of xaml for each box or at least an extra different solution to avoid that. – j riv Jun 05 '15 at 22:33
  • Perfect, this is a great solution. One central piece of code. Exactly what I was looking for. Thank you. – SQL Police Nov 01 '15 at 20:47
  • 1
    I found that the `MoveFocus` on sender did not work for me, but altering the line to MoveFocus on the e.OriginalSource as per the answer [here](http://stackoverflow.com/questions/14127577/why-does-uielement-movefocus-not-move-the-focus-to-the-next-sibling-element-in) did – mungflesh Apr 14 '16 at 08:03
  • @jriv The other answer (textbox_KeyDown) is not even remotely MVVM. The only way that one would work is to couple your view to your view model, forever inseparable, and hard to test. Yes, it works great if you're not trying to do MVVM, but if you're using WPF, then why aren't you doing MVVM? – NielW Aug 30 '16 at 18:34
  • @NeilW there is zero harm in baking UI logic into the UI. It's only the commands/text/state of the UI that MVVM models in the viewmodel to give you a layer that can be tested "like a user" – Rhys Bevilaqua Sep 08 '16 at 04:52
  • @Precog I really can't understand what's the purpose of writing the double if `if (e.Key == Key.Return) { if (e.Key == Key.Enter) ...` why not `if (e.Key == Key.Return || e.Key == Key.Enter) { ...`? Further, since Key.Enter and Key.Return have the same int value... why don't you simply write `if (e.Key == Key.Return) { ...` – Massimiliano Kraus Jan 05 '17 at 11:27
  • The references System.Windows.Interactivity doesn't exist , so i can use it. – luka Oct 02 '17 at 08:52
  • If you don't want to change focus but just trigger the binding, change the `MoveFocus` call to something like: `BindingOperations.GetBindingExpression( (DependencyObject)sender, TextBox.TextProperty )?.UpdateSource();` This allows you to *not* set the text box binding's `UpdateSourceTrigger` to `PropertyChanged`, which is sometimes undesirable. – metal Dec 17 '18 at 18:21