如何使文本框失去焦点?

8
如何使TextBox失去焦点并在用户触摸Enter虚拟按键时隐藏屏幕键盘?
    private void TheName_KeyDown(object sender, KeyRoutedEventArgs e) {
        var tb = sender as TextBox;
        if (e.Key == Windows.System.VirtualKey.Enter) {
            // ... tb.LooseTheFocus_PLEASE(); !???
        }
    }

3
实际上你不能直接这样做,你需要将焦点设置到另一个控件。 - Matthijs
如何做到呢?我已经尝试了 this.Focus(Windows.UI.Xaml.FocusState.Pointer) - 但被忽略了。 - Harry
尝试使用我的解决方案来隐藏Windows 8上的触摸键盘。 - Yang C
@Harry 这个应该也加上 UWP 标签。Win phone 8 已经死了,但是除此之外还是有用的。 - Denis G. Labrecque
5个回答

23
    /// <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);
        }
    }

它很丑陋,但是它能用。关键部分是IsTabStop属性。如果我不触碰它 - 键盘会消失一小段时间,然后重新出现。


与存储控件“IsTabStop”的状态并在更改后恢复相同,我建议您也对“IsEnabled”执行相同的操作。此外,可能有点挑剔,但我建议将“LoseFocus()”采用“Control”而不是“object”。最好向调用函数的人指示您需要他们传递一个“Control”,因为您在内部进行了强制转换(这只会冒险出现可轻松避免的无效转换异常,而且我真的不喜欢人们在不绝对必要的情况下使用“object”!)。 - Logix
@Logix 这个问题是不是本来就不可能让一个被禁用的控件获得焦点呢? - Beltway
@Logix 不应该有问题。但我不确定是否如此。我想唯一的方法就是在特定目标上进行测试。我认为这个黑客可以起作用,因为禁用的控件无法聚焦。所以我们让聚焦的控件失效,这样它就会失去焦点。然后我们启用它,因为它一开始就是启用的。默认的用户输入流程是输入字段值、输入键、输入字段、输入键、提交按钮。这就是用户期望的,这个黑客使它能够按照这种方式工作。 - Harry

5

将焦点设置到页面上。

this.Focus();

1
这在WP 8.1应用程序中不起作用。Focus需要一个参数,但无论我提供什么,虚拟键盘都会一直停留,直到我点击文本框外的空白区域。 - Harry
3
键盘即使在焦点改变后也不会消失。 - Pantelis
谢谢,完全正确! :) - Harry
不错的发现 @Pantelis! - Matthijs
1
这在WP 10中有效。使用this.Focus(FocusState.Programmatic); - miken.mkndev
对我来说,这只是将焦点设置到页面 this 中唯一的 TextBox 上,而我想要移除焦点的元素正是它。 - Denis G. Labrecque

3
要在UWP应用程序中取消焦点,只需执行以下操作:
private void Input_KeyDown(object sender, KeyRoutedEventArgs e)
{
    if (e.Key == VirtualKey.Enter)
    {
        //Do what you want upon enter
        this.Focus(FocusState.Programmatic);
    }
}

1

无法通过编程方式从控件中移除焦点。

一个选项是将焦点设置到表单上的另一个控件,比如一个标签,该标签解释了应在您的文本框中输入什么样的文本。

这会导致文本框失去焦点。

this 关于 Control.Focus() 的文档所示:

您不能通过使用 FocusState.Unfocused 作为参数调用此方法来从控件中移除焦点。此值不允许并会导致异常。要从控件中移除焦点,请将焦点设置到不同的控件上。

只需使用 Control.Focus(FocusState.Programmatic) 来设置焦点。任何控件都可以。


无法工作。当我尝试将焦点设置在标签(或任何其他元素)上时,什么也不会发生。 - Harry
1
我不想这么说,但我试过了,它不起作用。我设置了FocusState.Programatic - 但是该行被忽略了。我尝试了所有可能的Focus()参数值,但没有成功。我试图将页面、网格、TextBlock元素聚焦,但它就是不工作。我将代码放在KeyDown处理程序中,也许它不能从那里调用? - Harry
你的事件被触发了吗?设置一个断点,看看它是否进入了你的事件。 - Matthijs
是的,它已经触发了,让我在这里回答自己的问题,有一个丑陋的技巧可以使它工作... - Harry
我实际上读了Pantelis在他的评论中给出的答案。方法不太好,但如果没有其他办法.. ;) - Matthijs

0

如果您有多个文本框,只需在它们之间切换焦点即可。

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

无论哪个元素获得焦点,它都会失去焦点并触发任何所需的事件。
作为替代方案,可以将焦点放在页面上任何位置的隐藏文本框中。

1
您无法将焦点设置在隐藏元素上。 - Elmue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接