当按钮处于活动控制状态时,我需要根据箭头按下来调节程序流程。像这样:
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?
答案 0 :(得分:3)
好的,我做了一些有效的研究,在处理之前捕获了箭头键的key_down事件......
工作原理
按下某个键时,以下是控件内部发生的事件列表:
调用函数PreProcessControlMessageInternal
。
此函数将在控件上引发事件PreviewKeyDown。
然后它会调用PreProcessMessage
。
调用函数PreProcessMessage
。
此函数实际检查是否有人想要使用已按下的键。在我们的例子中,(WM_KEYDOWN):
Control首先调用ProcessCmdKey
:如果有人想确定这是一个命令键,则返回True并使用该键。没有其他人会看到钥匙已经关闭
然后控件调用IsInputKey()
:如果有人认为这是输入键(例如TextBoxes),则返回True并处理您的密钥。
然后调用ProcessDialogKey()
:[来自ReferenceSource的Litterally]
调用来检查对话框键,如TAB,箭头键和助记符
怎么做
在你的情况下,你有三种可能性,最后一种是最好的(也是最简单的):
在ProcessDialogKey()
收到邮件时处理邮件:
Protected Overrides Function ProcessDialogKey(keyData As Keys) As Boolean
If keyData = Keys.Up Or keyData = Keys.Down Or keyData = Keys.Left Or keyData = Keys.Right Then
'Do whatever you want with the key
Return True 'So the processing will stop
End If
Return MyBase.ProcessDialogKey(keyData)
End Function
阻止处理此密钥,以便您可以在Button_keyDown()
Protected Overrides Function ProcessDialogKey(keyData As Keys) As Boolean
If keyData = Keys.Up Or keyData = Keys.Down Or keyData = Keys.Left Or keyData = Keys.Right Then
Return False
End If
Return MyBase.ProcessDialogKey(keyData)
End Function
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
最佳方式
实际上(并且基于Zohar Peled的评论),最好的方法是处理PreviewKeyDown事件,因此您不必覆盖任何其他方法:
Private Sub Form1_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles MyBase.PreviewKeyDown
'Do whatever here, all the keydown events will fall into this sub.
End Sub
答案 1 :(得分:0)
我注意到KeyUp与Button上的Arrow-Keys一起使用,而KeyDown则没有。这有助于解决您的问题吗?
答案 2 :(得分:0)
此代码仅在焦点位于按钮上时才有效。
将此代码放置在表单级别,因此具有焦点的所有控件都将传递该事件...
Private Sub myForm_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Up Then
If mode = mymodes.first Then
firstcontrol.Focus()
Else
secondcontrol.Focus()
End If
End If
End Sub
答案 3 :(得分:0)
根据this question的答案,我提出了这个问题(在我的计算机上测试并运行)
Private Sub Form1_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles MyBase.PreviewKeyDown
If Me.Button1.Focused Then
If e.KeyCode = Keys.Up Then
If mode = mymodes.first Then
firstcontrol.Focus()
Else
secondcontrol.Focus()
End If
End If
End If
End Sub
默认情况下,key_down事件不会处理箭头键,但它们由PreviewKeyDown
事件处理。