适用于多种控件的Keydown Handler

时间:2012-10-01 06:49:50

标签: vb.net winforms

对于繁忙表单上的许多控件,是否有更好的方法来使用keydown处理程序? (在某些情况下,单独使用表单处理程序不起作用。)

Private Sub rText_KeyDown(ByVal Sender As Object, ByVal e As KeyEventArgs) Handles rText0.KeyDown, txTaxon.KeyDown, txCommon.KeyDown, _
  txConfidence.KeyDown, txDate.KeyDown, txDateAdded.KeyDown, txFileName.KeyDown, txGPS.KeyDown, txRating.KeyDown, _
  txConfidence.KeyDown, txQuality.KeyDown, txRemarks.KeyDown, txKeyWords.KeyDown, txOriginalPath.KeyDown, txDateAdded.KeyDown, _
  txLink.KeyDown, chkLink.KeyDown, rview.KeyDown, cmdNext.KeyDown, tvTaxon.KeyDown, Me.KeyDown, _
  cmdTaxon.KeyDown
Call globalkey(e)
End Sub

2 个答案:

答案 0 :(得分:2)

我是C#程序员,因此无法提供有效的解决方案(如在vb.net代码中)。

我认为你可以通过做以下事情来实现这一目标。

  1. 为您的各个控件编写AddHandler的方法,当且仅当他们将特定值设置为属性时(下面的步骤#2中的详细信息)
  2. 要将公共处理程序附加到的所有控件将其Tag属性设置为唯一值,例如:"KeyDown"。我建议在这种情况下使用Enum,而不是string
  3. 现在,在Form构造函数中,在InitializeComponent调用之后,调用您在上面#1中编写的方法。这会将处理程序附加到所有需要的控件上。
  4. 如果您有多个具有此要求的表单,则可以将此功能添加到主表单,该表单的作用类似于所有其他表单的父表单(继承)
  5. 希望我足够清楚,这会有所帮助。

答案 1 :(得分:2)

我喜欢AYK的回答。你可以使用这样的函数:

Public Shared Function GetAllControlsRecurs(ByVal list As List(Of Control), _
  ByVal parent  As Control, ByVal ctrlType As System.Type) As List(Of Control)
    If Parent Is Nothing Then Return list
    If Parent.GetType Is ctrlType Then
        list.Add(Parent)
    End If
    For Each child As Control In Parent.Controls
        GetAllControlsRecurs(list, child, ctrlType)
    Next
    Return list
End Function

我发现这是一个方便的函数,可以在某些父控件中获取给定类型的所有控件(包括控件内的控件)。通过按照AYK建议的方式标记您的控件(即:在设计器中设置Tag属性),您可以运行上面的所有控件并以编程方式添加处理程序(可能在构造函数中)。

Dim textboxList As New List(Of Control)

For Each ctl As TextBox In GetAllControlsRecurs(textboxList, Me, GetType(TextBox))
    If ctl.Tag = MyTags.rTextKD then 
        AddHandler ctl.KeyDown, AddressOf rText_KeyDown
    End If
Next

您可以将MyTags定义为枚举,其中包含您要实现的常用处理程序列表。这里rTextKD将是枚举的成员(我在答案中没有定义)。这种方法的好处在于它是可扩展的 - 如果你添加一个新的控件并标记它,那么这段代码就会把它拿起并连接处理程序而不需要改变。

虽然以上是您直接问题的答案,但如果您尝试制作全球热键,则不是这样做的方法。汉斯在评论中提供的链接可能就是您想去的地方。