【问题标题】:Keydown Handler for Many Controls许多控件的 Keydown 处理程序
【发布时间】:2012-10-01 19:11:49
【问题描述】:

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

【问题讨论】:

  • @HansPassant 我不认为这真的是那个问题的重复,尽管他可能正试图以一种笨拙的方式实现全局热键。没有更多上下文很难说。
  • @J... 我不想实现全局快捷方式。我只是为被调用的 sub 使用了一个错误的名称“globalkey”。
  • @HansPassant 该问题的答案肯定适用,但这两个问题并不重复——搜索一个的人不可能找到另一个。
  • 好吧,有人怎么能从这个问题中猜到呢?如果你想要一个更好的方法,那么至少记录下“globalkey”实际上做了什么。

标签: vb.net winforms


【解决方案1】:

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

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

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

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

【讨论】:

  • 那么你是在表单设计器中设置所有控件的标签吗?那为什么不直接在表单设计器事件选项卡中连接事件,避免所有特殊代码呢?
  • 他希望它用于某些选定的控件,并且他可能决定将来再添加 10 个控件。因此,我们可以使用 tag 属性标记这些控件,而不是在 UI 中添加处理程序,它们会自动应用。
  • @MarkJ 如果它是 C#,它不会有什么不同。然而,VB 坚持每次你这样做时都扩展处理程序的声明,Handles ... 等。如果你有很多组件共享一个处理程序,它会产生一大堆凌乱的代码。我认为 OP 所追求的是一种摆脱 Handles 后面的大量组件名称的方法。
【解决方案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 将是枚举的成员(我没有在答案中定义)。这种方法的好处是它是可扩展的——如果你添加一个新的控件并标记它,那么这段代码会选择它并连接处理程序,而无需更改。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多