即使使用keypreview = true,Button也可以防止触发KeyDown事件

时间:2013-08-16 19:43:18

标签: c# winforms keyboard-events

在VS Express 12中重现的步骤:

  • 创建新的Windows窗体应用程序项目
  • 添加按钮
  • 将表格KeyPreview设置为true
  • 将keyDown事件添加到表单
  • 只要表单上有按钮
  • ,事件就不会触发

我有一个项目,我想要捕获keydown和keyup事件,但是,我似乎只能让keyup事件工作。

我的表单上有一个面板,按钮和标签。在表单中,keyPreview属性设置为true,并链接到KeyDown和KeyUp事件。 但是,当我运行程序时,只触发KeyUp事件。

我尝试通过添加

手动添加事件处理程序
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);

但它仍然不起作用。

有什么建议吗?

KeyUp事件:

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        TriggerKey(e.KeyCode, false);
    }

    private void TriggerKey(Keys e, Boolean pKeyDown)
    {
        switch (e)
        {
            case Keys.Left:
                mLeft = pKeyDown;
                break;

            case Keys.Right:
                mRight = pKeyDown;
                break;

            case Keys.Down:
                mDown = pKeyDown;
                break;

            case Keys.Up:
                mUp = pKeyDown;
                break;
        }
    }

我的Form1_KeyDown事件如下所示:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    TriggerKey(e.KeyCode, true);
}

EDIT2: 我尝试从表单中删除按钮,然后两个事件都正确触发。如果我重新添加它,keyDown事件将再次停止工作。为什么按键在设置keypreview属性时会干扰?

4 个答案:

答案 0 :(得分:2)

KeyPreview是一个VB6兼容性功能,它不是“原生”Winforms。它有一个与您的问题完全匹配的问题。在查看KeyPreview的代码有机会运行并触发KeyDown事件之前,还有其他Form方法首先在按键上获取嗅探。他们先吃掉导航键。就像您试图看到的光标键以及Tab键一样。这符合VB6的行为,也无法看到光标键。

要保持领先于该代码,您需要覆盖表单的ProcessDialogKey()方法。像这样:

    protected override bool ProcessDialogKey(Keys keyData) {
        switch (keyData) {
            case Keys.Left:
                //...
                return true;
        }
        return base.ProcessDialogKey(keyData);
    }

答案 1 :(得分:0)

你在keyDown上设置mUp ......?你可以添加所有相关的代码上下文,例如鼠标注册事件,你也可以尝试刷新,如果你打破了按键时甚至点火了吗?

答案 2 :(得分:0)

请注意,keydown后会引发keyup(如果你希望mUp保持为true)

答案 3 :(得分:0)

我在其他类似的帖子中看到这可能会有所帮助

this.focus();

尝试一下,让我知道继续寻找其他方式