再次点击文本框取消聚焦

3

我正在制作一个设置表单,用户可以为应用程序分配自定义热键。有一个文本框,通过鼠标点击它,它会聚焦并等待一个按键,然后失去焦点(通过聚焦另一个标签):

private void txtKey_KeyDown(object sender, KeyEventArgs e)
{
    e.SuppressKeyPress = true;
}

private void txtKey_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    TextBox textBox = (TextBox)sender;
    textBox.Text = e.KeyCode.ToString();
    label1.Focus();
}

有没有办法通过再次用鼠标单击它或者点击其周围的GroupBox来取消键盘输入过程从而使已经获得焦点的TextBox失去焦点?我无法判断在单击时TextBox是否已经获得了焦点(因为在测试之前,单击操作会使其获得焦点)。当然我可以在TextBox旁边添加一个“取消”按钮,但这不是我想要的。GroupBox没有Click事件,所以我不能通过单击其周围的GroupBox来使TextBox失去焦点,或者有什么其他办法吗?

为什么不直接在 GroupBox 中使用 Panel 控件,因为 PanelMouseClick 事件。 - sallushan
这个方法可以用。如果我找不到更好的解决方案,我会使用它。问题是我还必须为面板内的所有标签设置单击事件,并将面板添加到所有GroupBoxes中。而且,GroupBox边框仍然无法工作,所以这种方法有点不太干净,但还是谢谢! - darx
如果对话框除了“确定”和“取消”按钮之外没有其他控件可以聚焦,那么“取消”有什么意义呢?用户根本没有好的理由使用键盘。 - Hans Passant
用户可能总是想要按下 EscEnter(就像我经常做的那样)来关闭或应用并关闭对话框。这样做将会将该键注册为热键。当然,用户始终可以单击“取消”以在不保存的情况下关闭对话框,但通过再次单击文本字段来取消分配过程会感觉更加“专业”。至于我的答案,我有一个可行的解决方案。(添加了一张图片来展示对话框的一部分,活动文本框的颜色不同且正在等待按键输入。http://www.saunalahti.fi/arka80/web/hotkey.png) - darx
3个回答

0

你可以使用以下代码设置/移除焦点:

Keyboard.Focus = null;

您也可以注册以下活动:

public event MouseButtonEventHandler PreviewMouseLeftButtonDown

每次单击TextBox时,此事件都会触发,因此如果需要,可以将焦点设置在那里。

对于Winforms也有一种方法。我不熟练,但这里是一种方法: 创建一个文本框(例如命名为textBoxFocus),它位于您的窗口之外。将其大小设置为1,1并将其移动到-10,-10。然后,您可以注册Click事件并编写:

textBoxFocus.Focus();

这可能有点绕,但应该能实现你想要的功能。


谢谢,但这些是与WPF相关的内容,而不是WinForms? - darx
嗨,没问题!但是这不是与我的问题描述中聚焦一个没有文本的标签相同吗?问题在于,如果我注册TextBox点击事件以聚焦另一个控件,我永远无法聚焦TextBox以分配热键。我想要的是,当TextBox已经聚焦时,如果我再次点击它,则聚焦其他某个控件。 - darx
那么你可以使用@sallushan在回复中提到的方法,或者使用一个面板。否则,你需要注册GotFocus和LostFocus事件,当你获得焦点时,设置一个标志,当你单击并且你已经设置了标志,你就知道你需要取消焦点。然后,重置标志。 - private_meta
我尝试过这个,使用Enter事件(在VS中它是焦点类别下的)。只是当我点击TextBox时,Enter事件会在Click事件之前触发,所以标志位总是在我能够用Click事件检查它之前被设置。 - darx

0
感谢 private_meta 在评论中给了我正确的方向!我使用点击事件设置标志,在设置标志之前测试标志是否已设置。因此,第一次单击无法找到标志,但第二次单击将会找到。并且在文本框输入事件(在单击事件之前触发)中清除标志。现在每隔一个单击事件就会聚焦和失焦文本框,正如我所希望的那样。
private void txtKey_Enter(object sender, EventArgs e)
{
    TextBox textBox = (TextBox)sender;
    textBox.Tag = null;
}

private void txtKey_Click(object sender, EventArgs e)
{
    TextBox textBox = (TextBox)sender;
    if (textBox.Tag != null) label1.Focus();
    textBox.Tag = "clicked";
}

0

其中一种简单的方法是,您可以在此处使用bool标志。

算法:
By default, the bool value is 0;
If(Textbox Selected && flag = 0)
    Do your task; and flag = 1;

我希望我能满足您的查询需求,您可以按照这个算法进行操作。


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