按钮即使设置keypreview=true也会阻止KeyDown事件触发

3

在VS Express 12中重现步骤:

  • 创建一个新的Windows Forms应用程序项目
  • 添加一个按钮
  • 将表单的KeyPreview属性设置为true
  • 为表单添加一个keyDown事件
  • 只要按钮存在于表单上,该事件就不会触发

我有一个项目,我想捕获按键按下和松开事件,但是似乎只能让松开事件起作用。

我有一个表单,上面有一个单独的面板、按钮和标签。在表单中,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);
}

编辑2: 我尝试从我的表单中移除按钮,然后两个事件都正确触发。如果我将它重新添加回去,keyDown事件就再次停止工作。当keypreview属性被设置时,为什么按钮会干扰呢?


1
这是使用Windows Forms还是WPF?C#没有KeyDown事件。 - John Saunders
我也尝试过,但如果焦点是问题的话,KeyPreview应该能够解决它,而keyUp事件不应该被触发吧? - Oleball
@JohnSaunders 这是关于Windows窗体的。如果我表述不太清楚,抱歉。那个是问题吗? - Oleball
更新keyup事件以使其更有意义,因为很多人都在评论它。 - Oleball
欢迎来到 Stack Overflow。非常好的第一个问题 - 就提供的信息而言! - Brian
显示剩余2条评论
4个回答

3
KeyPreview是VB6兼容功能,不是原生Winforms。它有一个问题正好与您的问题相匹配。还有其他窗体方法会在查看KeyPreview的代码有机会运行并触发KeyDown事件之前先捕捉到按键。而且它们首先捕捉导航按键,如您尝试查看的光标键和Tab键。这与VB6的行为匹配,因为VB6也看不到光标键。
为了保持领先,您需要覆盖表单的ProcessDialogKey()方法。像这样:
    protected override bool ProcessDialogKey(Keys keyData) {
        switch (keyData) {
            case Keys.Left:
                //...
                return true;
        }
        return base.ProcessDialogKey(keyData);
    }

那个运行得非常完美,感谢您的详细说明!在这种情况下,对于所有键而不仅仅是方向键都是如此。这是否被认为是已知的错误? - Oleball
这不是一个漏洞,而是完全按设计来的。 - Hans Passant
我会说“这不是一个bug,而是一种特性” :) - King King

0

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

this.focus();

试一试,让我知道是否需要继续寻找其他方法。


0

你是在按下键时设置mUp吗?能否添加所有相关的代码上下文,例如鼠标抬起事件,如果出现错误,你可以尝试刷新一下页面,看看按键是否触发了事件?


除了KeyUp和KeyDown事件之外,没有其他事件,我现在添加了KeyUp事件代码。还有其他代码片段需要我添加吗? - Oleball
欢迎来到SO,@BunnyStrider。将来,像您这样的帖子更适合作为评论而不是答案。 - Brian

0
请注意,如果您希望mUp保持为true,则keyup事件会在keydown事件之后触发。

已修正,现在意义更明确了。但是KeyDown事件仍未触发。 - Oleball
但是在按上箭头后,它将变为false。你怎么知道事件不起作用? - Feri
断点和当我从表单中移除按钮时,它能够正确地工作。 - Oleball
如果你看了我的问题,你会发现我已经设置了那个属性。还是感谢你的努力。 - Oleball

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