可以'在特定情况下,无法从ToolStripTextBox中转义



很难描述这个问题。让我用一个非常简单的例子来说明。从winform(.net framework 4.8(的新解决方案开始。添加一个带有文本框的菜单条,然后添加一个数据网格视图。让我们来处理datagridview的KeyDown事件。

if (e.KeyCode == Keys.F3)
toolStripTextBox1.Focus();

好的,现在我们开始这个程序。

  1. 单击数据网格视图以关注它
  2. 单击文本框以更改焦点
  3. 按键盘上的Esc键

您可以看到datagridview获得了预期的焦点。

但是,如果你在第二步做一点改变,结果会令人困惑。​按F3而不是单击文本框。​这次按Esc键时,焦点会丢失。​我试着打印名称和焦点控制的句柄。原来是文本框本身。​有人能解释一下吗?

现在我很确定这是某种bug。在吉米提到hwndThatLostFocus之后,我追踪了这个变量好几个小时。虽然我没有找到hwndThatLostFocus更改的确切位置,但发现了一些不合理的地方:当在不同情况下调用Focus()时,结果失去了一致性。

在大多数情况下,如果调用ToolStripTextBox的Focus(),则ToolStripTextBox的hwndThatLostFocus将设置为0,就像我问题中的示例一样。但是,如果您单击数据网格视图并单击ToolStripTextBox,然后单击数据网格查看agian,那么这次调用Focus()时,hwndThatLostFocus将仍然是指向数据网格视图的指针。此外,这一点可在.net 6中转载。

稍后我将向Microsoft报告此情况。目前,有三种方法可以避免这种情况。

  1. 通过user32.dll中的SetCursorPosmouse_event模拟鼠标单击。

  2. 像吉米的建议一样进行反思。

  3. Form中覆盖ProcessCmdKey,自己照顾Keys.Escape

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
    if (keyData == Keys.Escape && msg.HWnd == toolStripTextBox1.TextBox.Handle)
    {
    dataGridView1.Focus();
    return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
    }
    

因为我避免使用不必要的反射,而且Dllimport对我来说也有点难看,所以我更喜欢第三种。

相关内容

  • 没有找到相关文章

最新更新