3

在 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

4 回答 4

3

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);
    }
于 2013-08-16T20:43:01.037 回答
0

请注意,keyup 在 keydown 之后引发(如果您希望 mUp 保持真实)

于 2013-08-16T19:57:10.323 回答
0

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

this.focus();

试一试,让我知道继续寻找其他方法

于 2013-08-16T20:38:49.500 回答
0

您在 keyDown 上设置 mUp ...?你可以添加所有相关的代码上下文,比如鼠标向上事件,你也可以尝试刷新,如果你打破了即使按下键也会触发?

于 2013-08-16T19:46:03.507 回答