【问题标题】:VB.NET - How to add a large amount of events to a single handle?VB.NET - 如何将大量事件添加到单个句柄?
【发布时间】:2019-09-14 23:30:04
【问题描述】:

最近我一直在开发一个包含几个文本框、复选框、组合框等的程序,我发现让一个函数处理多个事件非常简单,只需用逗号分隔事件和代码识别个别事件。

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click, Button2.Click
    MsgBox("Hello World!")
End Sub

但是,当您开始有大量事件要由同一个函数处理时,它会变得有点混乱。

Private Sub Checks_CheckedChanged(sender As Object, e As EventArgs) Handles chkInput1.CheckedChanged, chkInput2.CheckedChanged, chkInput3.CheckedChanged, chkInput4.CheckedChanged, checkInput5.CheckedChanged, chkOutput.CheckedChanged
    MsgBox("Checks Changed!")
End Sub

您可以使用续行符_ 让它看起来更好一点。

Private Sub Checks_CheckedChanged(sender As Object, e As EventArgs) Handles _
chkInput1.CheckedChanged, chkInput2.CheckedChanged, chkInput3.CheckedChanged, _
chkInput4.CheckedChanged, checkInput5.CheckedChanged, chkOutput.CheckedChanged
    MsgBox("Checks Changed!")
End Sub

但你仍然会得到一个令人讨厌的文本块。有没有更干净/简洁的方法来做到这一点?我的想法是,将一组对象事件作为参数是非常好的,但我认为这是不可能的。

【问题讨论】:

  • 您始终可以在运行时连接事件:AddHandler chkInput1.CheckedChanged, AddressOf Checks_CheckedChanged
  • 在表单的构造函数 (Sub New()) 中添加处理程序。请注意,sender 对象可以转换为 CheckBox。这将为您提供引发事件的控件。如果处理程序中的代码简单/简短,您还可以使用 lambda (Sub()) 作为委托,而不是 AddressOf
  • @Jimi 我对您的解决方案很感兴趣,但很困惑。通过将处理程序添加到构造函数,它如何使其处理多个事件?您是否仍然不必设置函数以某种方式处理哪些事件?
  • Sub New()InitializeComponent() 之后For Each chkBox As CheckBox In Me.Controls.OfType(Of CheckBox).ToArray() AddHandler chkBox.CheckedChanged, Sub() chkBox.BackColor = If(chkBox.Checked, Color.Red, Color.Green) Next。现在,尝试检查/取消选中您的复选框(此处为表单的直接子级),看看会发生什么。
  • 在实践中,您会得到相同的结果。但是您总是希望您的Load() 处理程序过程尽可能轻(未订阅?更好)。这个事件还有一个问题:它吞噬了异常。它还会减慢表单的呈现速度。

标签: vb.net winforms events


【解决方案1】:

你可以通过使用

AddHandler ObjectName.EventName, AddressOf EventHandlerName

语法

编写一个接收对象数组并循环遍历它们以添加每个事件的处理程序的 Sub 非常简单。

对于复选框:

Public Sub AddHandlerSub(PassedArray As CheckBox())
    For Each item As CheckBox in PassedArray
        AddHandler Item.CheckedChanged, AddressOf EventHandlerName
    next
End Sub

【讨论】:

  • 精彩的回答,非常感谢。我喜欢这个,因为它适用于设计器中添加的控件以及动态添加的控件。
  • removing those handlers 呢?
  • @Çöđěxěŕ 将 AddHandler 替换为 RemoveHandler 即可。
  • 如果您希望RemoveHandler 工作以确保您与处理程序签名完全匹配(Option Strict On 将保证这一点),这一点也非常重要。
【解决方案2】:

您可以简单地对控件集合中的控件进行迭代,而不用对数组大惊小怪。如果你想排除/添加任何给定的控件,你也可以做更多的条件,比如下面例子中的 TextBox Case。

Private Sub DataTables_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    For Each Ctrl As Control In Panel1.Controls
        Select Case Ctrl.GetType
            Case GetType(CheckBox)
                AddHandler DirectCast(Ctrl, CheckBox).CheckedChanged, Sub(S As Object, EA As EventArgs)
                                                                          Dim ChkBox As CheckBox = DirectCast(S, CheckBox)
                                                                          'do something with ChkBox
                                                                      End Sub

            Case GetType(TextBox)

                Select Case Ctrl.Name
                    Case "TextBox1", "TextBox2" 'Add handle only to these contrls
                        'Or you could add Case Else and put the below handle within it
                        'Then this becomes an exclusion case
                        AddHandler DirectCast(Ctrl, TextBox).TextChanged, Sub(S As Object, EA As EventArgs)
                                                                              Dim TxtBox As TextBox = DirectCast(S, TextBox)
                                                                              'do something with TxtBox
                                                                          End Sub
                End Select

        End Select

    Next
End Sub

【讨论】:

    【解决方案3】:

    附加信息:您可以通过选择控件来选择过程作为事件处理程序。然后在“属性”窗口中单击闪电以显示事件。选择您希望分配处理程序的事件,然后选择右侧的下拉箭头。结果列表将显示与该事件的签名匹配的所有 Subs。选择您想要的,设计者将编写或附加控件到 Handles 子句。

    使用与事件匹配的签名向表单添加过程。

    Private Sub MultipleButtons(sender As Object, e As EventArgs)
    
    End Sub
    

    在下拉列表中,列表包含与事件签名匹配的所有 Subs。

    设计者编写 Handles 子句

    Private Sub MultipleButtons(sender As Object, e As EventArgs) Handles Button5.Click
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 2011-08-28
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      相关资源
      最近更新 更多