.NET WinForms中的KeyDown事件为什么不触发?

10

我已经在窗体属性中将KeyPreview设置为true

我正在开发一个小程序,但是当我按下并释放任何箭头键时,它似乎有些控件(位于GroupBox内)没有触发窗体的KeyDown事件,只触发了KeyUp事件。是否我的代码有问题导致这种情况发生?

具体地说,我已经在窗体上启用了KeyPreview,并在两个子例程的e.SuppressKeyPress = True处设置了断点,只有frmMain_KeyUp的那个例程触发了断点。

我添加了两个GroupBox事件,希望这可以缓解问题,但没有这样的运气。但是,我在窗体上有一个自定义控件,专门编写了忽略这些按键的代码,该代码按预期工作。

  Private Sub frmMain_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown, GroupBox1.KeyDown, GroupBox2.KeyDown
      e.SuppressKeyPress = True
      Select Case e.KeyCode
          Case Keys.Left
              ScrollDir = ScrollDir Or 1
          Case Keys.Right
              ScrollDir = ScrollDir Or 2
          Case Keys.Down
              ScrollDir = ScrollDir Or 4
          Case Keys.Up
              ScrollDir = ScrollDir Or 8
          Case Else
              e.SuppressKeyPress = False
      End Select
      tScroll.Enabled = True
      tScroll_Tick(Nothing, Nothing)
  End Sub

  Private Sub frmMain_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp, GroupBox1.KeyUp, GroupBox2.KeyUp

      e.SuppressKeyPress = True
      Select Case e.KeyCode
          Case Keys.Left
              ScrollDir = ScrollDir And (Not 1)
          Case Keys.Right
              ScrollDir = ScrollDir And (Not 2)
          Case Keys.Down
              ScrollDir = ScrollDir And (Not 4)
          Case Keys.Up
              ScrollDir = ScrollDir And (Not 8)
          Case Else
              e.SuppressKeyPress = False
      End Select
      If ScrollDir = 0 Then tScroll.Enabled = False
  End Sub

在用户控件中“忽略”按键的代码如下:

    Private Sub TileDropDown_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyValue = 40 OrElse e.KeyValue = 38 OrElse e.KeyValue = 39 OrElse e.KeyValue = 37 Then

            e.SuppressKeyPress = True
        End If
    End Sub

在忽略控件的代码中设置一个断点,看它是否至少触发一次。 - curtisk
在frmMain的KeyDown处理程序中取消注释e.SuppressKeyPress = True后,TileDropDown_KeyDown子例程将不会被调用。如果将其注释掉,则处理程序被调用。 - Sukasa
2个回答

11

有些控件会在keydown事件中截获方向键,但不会在keyup事件中截获。一个解决办法是派生控件类并重写ProcessCmdKey:

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keydata As Keys) As Boolean

If keydata = Keys.Right Or keydata = Keys.Left Or keydata = Keys.Up Or keydata = Keys.Down Then
  OnKeyDown(New KeyEventArgs(keydata))
  ProcessCmdKey = True
Else
  ProcessCmdKey = MyBase.ProcessCmdKey(msg, keydata)
  End If
End Function

2
在vb.net中处理箭头键,加载函数中使用Me.KeyPreview = True,目标函数中使用(Handles Me.KeyUp)即可,不需要做太多操作。

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