按键预览未响应

5

无论如何,我的表单都不会触发PreviewKeyDown事件。 KeyPreview属性已经设置为True

Private Sub frmMain_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles MyBase.PreviewKeyDown
    'Code never hits this line
End Sub
1个回答

10

在.NET出现之前,VB6是主导的GUI开发工具。Winforms没有提供与VB6某种程度的向后兼容性,但KeyPreview是一项向后兼容的属性,VB6也有这个属性。在VB6中,这是实现快捷键的唯一方法,它会在控件获取焦点之前触发窗体的KeyDown事件。而不是PreviewKeyDown。

它还有一些VB6的怪癖,例如,对于像Tab、箭头键、Enter和Escape这样的导航键,KeyDown不会触发。这就是Winforms特定的PreviewKeyDown事件所涉及到的,它可以在执行导航操作之前嗅探此类按键。但只能在具有焦点的控件上进行,而当窗体具有任何控件时,它将永远不会成为焦点。

放弃此向后兼容功能并使用Winforms特定的键盘处理支持肯定是最好的选择,因为它减少了意外情况。实现快捷键的最佳方法是重写窗体的ProcessCmdKey()方法,它无条件运行,无论键或窗体的状态如何:

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
    If keyData = Keys.F1 Then
        '' Show help
        ''...
        Return True
    End If
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

2
这是一个非常好的答案。任何在WinForms应用程序中处理菜单项等内容的人都应该查看此内容。 - dotNET
我在测试修改器位时遇到了一些麻烦,因为启用了STRICT ON选项。 以下方法对我有效: Dim i As Integer = CType(keyData, Integer) Dim ic As Short = CShort(i \ 65536) Dim ik As Short = CShort(i Mod 65536) If ic = 2 AndAlso ik = Keys.A Then Debug.WriteLine("ctrlA pressed") End If - Martin

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