.NET Winforms箭头键的按键KeyDown

时间:2016-03-30 08:04:09

标签: .net vb.net winforms

当按钮处于活动控制状态时,我需要根据箭头按下来调节程序流程。像这样:

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 个答案:

答案 0 :(得分:3)

好的,我做了一些有效的研究,在处理之前捕获了箭头键的key_down事件......

以下是它开始的来源: http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,7765d3efe64d5539

工作原理

按下某个键时,以下是控件内部发生的事件列表:

调用函数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事件处理。