当按钮处于活动控制状态时,我需要根据箭头按下来调节程序流量 . 像这样:
Private Sub btn_OK_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles btn_OK.KeyDown
If e.KeyCode = Keys.Up Then
If mode = mymodes.first Then
firstcontrol.Focus()
Else
secondcontrol.Focus()
End If
End If
End Sub
正如我所看到的,按任意箭头键都不会触发KeyDown事件 . 程序改为执行一些内部功能,并使用表单的Tab键顺序移动焦点(看起来像) . KeyPreview在实际表单上设置为true .
有没有什么方法可以使用箭头键获得所需功能,而无需子类化按钮和使用ProcessCmdKey?
4 回答
好的,我做了一些有效的研究,在处理之前捕获了箭头键的key_down事件......
以下是它开始的来源:http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,7765d3efe64d5539
How it works
按下某个键时,以下是控件内发生的事件列表:
调用函数
PreProcessControlMessageInternal
.此函数将在控件上引发事件PreviewKeyDown . 然后它将调用
PreProcessMessage
.调用函数
PreProcessMessage
.此函数实际检查是否有人想要使用已按下的键 . 在我们的例子中,(WM_KEYDOWN):
控件首先调用
ProcessCmdKey
:如果有人想确定这是一个命令键,则返回True并使用该键 . 没有其他人会看到钥匙已关闭然后控件调用
IsInputKey()
:如果有人确定这是输入键(例如TextBoxes),则返回True并处理您的密钥 .然后它调用
ProcessDialogKey()
:[来自ReferenceSource的Litterally]调用>来检查对话框键,如TAB,箭头键和助记符
What to do
在你的情况下,你有三种可能性,最后一种是最好的(也是最简单的):
Process the message when ProcessDialogKey() receives it :
Prevent the handling of this key so you can handle it in Button_keyDown()
The Best Way
实际上(并且基于Zohar Peled的评论),最好的方法是处理PreviewKeyDown事件,因此您不必覆盖任何其他方法:
此代码仅在焦点位于按钮上时才有效 .
将此代码放在表单级别,因此具有焦点的所有控件都将传递该事件...
我注意到KeyUp与Button上的Arrow-Keys一起工作,而KeyDown没有 . 这会对您的问题有所帮助吗?
根据this question的答案,我想出了这个(在我的电脑上测试并工作)
事实证明,默认情况下,key_down事件不会处理箭头键,但它们由
PreviewKeyDown
事件处理 .