KeyDown 可以识别左右方向键,但无法识别上下方向键。

6
以下代码中,左右箭头键的功能正常,但上下箭头键无法识别(通过逐步调试,发现前两个条件在适当情况下得到满足,但后两个条件从未得到满足):
private void textBox1_KeyDown(object sender, KeyEventArgs e) {
    TextBox tb = (TextBox)sender;

    if (e.KeyCode.Equals(Keys.Left)) {
        SetFocusOneColumnBack(tb.Name);
        e.Handled = true;
        return;
    }
    if (e.KeyCode.Equals(Keys.Right)) {
        SetFocusOneColumnForward(tb.Name);
        e.Handled = true;
        return;
    }
    if (e.KeyCode.Equals(Keys.Up)) {
        SetFocusOneRowUp(tb.Name);
        e.Handled = true;
        return;
    }
    if (e.KeyCode.Equals(Keys.Down)) {
        SetFocusOneRowDown(tb.Name);
        e.Handled = true;
        return;
    }
}

为什么会出现这种情况,我该如何解决?

更新

当我逐步执行时,鼠标停留在 e.Keycode 上面所看到的内容如下:

  • ...左箭头键: e.KeyCode = "LButton | MButton | Space"
  • ...右箭头键: e.KeyCode = "LButton | RButton | MButton | Space"
  • ...上箭头键: e.KeyCode = "RButton | MButton | Space"
  • ...下箭头键: e.KeyCode = "Backspace | Space"

这让我感到十分困惑(它向我展示了什么),但是在按下左箭头键和右箭头键时,我的代码会被输入 - 无论我多么用力咬牙关上牙关,都不会对 keyup 和 keydown 产生影响。


1
在事件处理程序的开始处设置断点。它是否为上下键调用?如果没有,那么其他东西正在获取事件并在此处理程序有机会之前调用“e.Handled = true”。 - Alain
是的,我在原帖中提到了逐步执行它。 - B. Clay Shannon-B. Crow Raven
1
那么,当您逐步执行此代码时,这两种情况下 e.KeyCode 的值是什么? - Alain
好问题;以上已回答(我已更新了我的帖子) - B. Clay Shannon-B. Crow Raven
我也在想,处理此事件的其他某些东西可能尝试对其成员值进行错误的按位组合,最终导致其被修改。 - Alain
显示剩余2条评论
4个回答

4

在发送到表单之前,Windows会捕获某些键以进行UI导航。如果您想覆盖此行为,则需要重载IsInputKey方法(并对文本字段进行子类化):

    protected override bool IsInputKey(Keys keyData)
    {
        if (keyData == Keys.Right)
            return true;
        return base.IsInputKey(keyData);
    }

3

我发现使用PreviewKeyDown确实起作用(我必须删除“e.Handled = true”代码,因为它不适用于PreviewKeyDown事件):

private void textBoxQH1_PreviewKeyDown(object sender,   PreviewKeyDownEventArgs e) {
    TextBox tb = (TextBox)sender;

    if (e.KeyCode.Equals(Keys.Up)) {
        SetFocusOneRowUp(tb.Name);
        return;
    }
    if (e.KeyCode.Equals(Keys.Down)) {
        SetFocusOneRowDown(tb.Name);
        return;
    }
}

因此,需要三个不同的事件来处理我所寻找的各种键:KeyPress用于普通字符,KeyDown用于非字符(左右箭头键),而PreviewKeyDown则用于上下箭头键。


使用 PreviewKeyDown,您可以在其他任何东西修改它之前获取 KeyCode。我猜测代码的其他地方正在进行错误的位运算并在到达 KeyDown 事件之前破坏代码。还要注意,您可以在此处在 PreviewKeyDown 事件中轻松处理 Keys.LeftKeys.Right,这意味着您只需要 2 个事件而不是 3 个。 - Alain
1
我认为Hampus Nilsson已经回答了为什么左右处理正确,而上下没有的问题。这启发了我尝试在Windows拦截它们之前拦截它们的拦截的想法。 - B. Clay Shannon-B. Crow Raven
1
在他们拦截之前拦截他们的拦截,+1。 - Alain

1

如果有人感兴趣,可以使用e.KeyValue,例如,左箭头键的e.KeyValue37,右箭头键的e.KeyValue39等等。


1
你可以使用这段代码:

private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Up:
            //Do stuff
            break;
        case Keys.Down:
            //Do stuff
            break;
        case Keys.Left:
            //Do stuff
            break;
        case Keys.Right:
            //Do stuff
            break;
    }
}

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