首页 文章

.NET Winforms箭头键的Button KeyDown

提问于
浏览
1

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

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

    好的,我做了一些有效的研究,在处理之前捕获了箭头键的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 :

    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
    

    Prevent the handling of this key so you can handle it in 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
    

    The Best Way

    实际上(并且基于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
    
  • 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

    我注意到KeyUp与Button上的Arrow-Keys一起工作,而KeyDown没有 . 这会对您的问题有所帮助吗?

  • 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 事件处理 .

相关问题