8

How to make TextBox lose its focus and hide onscreen keyboard when user touches Enter virtual key?

    private void TheName_KeyDown(object sender, KeyRoutedEventArgs e) {
        var tb = sender as TextBox;
        if (e.Key == Windows.System.VirtualKey.Enter) {
            // ... tb.LooseTheFocus_PLEASE(); !???
        }
    }
Harry
  • 4,524
  • 4
  • 42
  • 81
  • 3
    You can't actually. You have to set focus to another control. – Matthijs Jun 16 '14 at 20:08
  • How to do it? I've tried this.Focus(Windows.UI.Xaml.FocusState.Pointer) - ignored. – Harry Jun 16 '14 at 20:25
  • Try [my solution][1] about hidding touch-keyboard on Windows 8. [1]: http://stackoverflow.com/questions/20858141/keyboard-wont-dismiss-even-after-focus-change/29124111#29124111 – Yang C Mar 18 '15 at 17:02
  • @Harry This should probably be tagged with UWP as well. Win phone 8 is dead, but this is still useful otherwise. – Denis G. Labrecque Dec 28 '19 at 03:57

5 Answers5

22
    /// <summary>
    /// Makes virtual keyboard disappear
    /// </summary>
    /// <param name="sender"></param>
    private void LoseFocus(object sender) {
        var control = sender as Control;
        var isTabStop = control.IsTabStop;
        control.IsTabStop = false;
        control.IsEnabled = false;
        control.IsEnabled = true;
        control.IsTabStop = isTabStop;
    }

    /// <summary>
    /// Makes virtual keyboard disappear when user taps enter key
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void LooseFocusOnEnter(object sender, KeyRoutedEventArgs e) {
        if (e.Key == Windows.System.VirtualKey.Enter) {
            e.Handled = true; LoseFocus(sender);
        }
    }

It's ugly. But it works. The key part is IsTabStop property. If I don't touch it - the keyboard disappers for a fraction of a second and reapears again.

Harry
  • 4,524
  • 4
  • 42
  • 81
  • In the same way that you store whether or not the control `IsTabStop`, and then revert to that value after changing it, I'd recommend doing the same with `IsEnabled` too. Also, probably a bit of a nitpick, but I would recommend having `LoseFocus()` take a `Control` rather than an `object`. It's better to indicate to the person calling the function that you require them to pass in a `Control`, since you're casting to that internally (it just risks an easily-avoidable invalid cast exception, and I'm REALLY not a fan of people using `object` where it's not *absolutely* necessary!). – Logix Nov 21 '20 at 14:25
  • @Logix Is it even possible to have a disabled control focused in the first place? – Beltway Aug 08 '22 at 09:32
  • @Logix It shouldn't be. But IDK if it is. I guess the only way to find out is to test it on a specific target. I think this hack can work just because the disabled control cannot be focused. So we make the focused control disabled, that should unfocus it. Then we enable it, because it's enabled in the first place. The default user input flow is enter field value, enter key, enter field, enter key, submit button. That's what user expects, this hack makes it work that way. – Harry Aug 15 '22 at 10:01
5

Just set the focus to the page.

this.Focus();
Pantelis
  • 2,060
  • 3
  • 25
  • 40
3

To unfocus in UWP apps simply do:

private void Input_KeyDown(object sender, KeyRoutedEventArgs e)
{
    if (e.Key == VirtualKey.Enter)
    {
        //Do what you want upon enter
        this.Focus(FocusState.Programmatic);
    }
}
JTIM
  • 2,774
  • 1
  • 34
  • 74
1

There is no way to remove the focus from a control programmatically.

An option would be to set focus to another control on the form, say a label which explains what kind of text should be entered in your TextBox.

This causes the textbox to lose focus.

As shown in this documentation about Control.Focus():

You can't remove focus from a control by calling this method with FocusState.Unfocused as the parameter. This value is not allowed and causes an exception. To remove focus from a control, set focus to a different control.

Just use Control.Focus(FocusState.Programmatic) to set focus. Any control should do.

Matthijs
  • 3,162
  • 4
  • 25
  • 46
  • Doesn't work. Nothing happens when I try to set focus on label (or any other element). – Harry Jun 16 '14 at 20:32
  • 1
    I hate to say it, but I've tried this, and it doesn't work. I set FocusState.Programatic - and the line is just ignored. I've tried every possible value for Focus() argument with no luck. I've tried to focus the page, grid, TextBlock element, it just refuses to work. I put the code in KeyDown handler, maybe it cannot be invoked from there? – Harry Jun 16 '14 at 20:39
  • Is your event even fired? Set a breakpoint and see if it goes into your event. – Matthijs Jun 16 '14 at 20:40
  • Yes, it's fired, and let me answer my own question here, there's an ugly trick to make it work... – Harry Jun 16 '14 at 20:59
  • I actually read the answer Pantelis gave in his comment. Nasty solution but if nothing else works.. ;) – Matthijs Jun 16 '14 at 21:00
0

If you have multiple text boxes, just shift focus between them.

_first_tb.Focus(FocusState.Programmatic);
_secont_tb.Focus(FocusState.Programmatic);

No matter which one has the focus, it will drop the focus and fire any events that you need.

As an alternative, provide focus to a hidden text box placed anywhere on the page.

Eric
  • 389
  • 5
  • 8