4

有没有更好的方法来为繁忙表单上的许多控件设置 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
4

2 回答 2

2

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

我认为您可以通过执行以下操作来完成此工作。

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

希望我足够清楚,这会有所帮助。

于 2012-10-01T08:04:39.680 回答
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将是枚举的成员(我没有在答案中定义)。这种方法的好处是它是可扩展的——如果你添加一个新的控件并标记它,那么这段代码将选择它并连接处理程序,而无需更改。

虽然以上是对您直接问题的回答,但是如果您尝试制作全局热键,那么这不是这样做的方法。Hans 在评论中提供的链接可能是您想去的地方。

于 2012-10-01T11:03:43.297 回答