【问题标题】:Dynamic button click event handler动态按钮单击事件处理程序
【发布时间】:2011-09-10 22:19:44
【问题描述】:

我在一个表单中动态创建了 100 个按钮。如何向它们添加事件处理程序?

【问题讨论】:

标签: vb.net


【解决方案1】:

您可以使用AddHandler 为任何事件添加处理程序。

例如,这可能是:

AddHandler theButton.Click, AddressOf Me.theButton_Click

【讨论】:

  • 如果您以编程方式处理按钮,请不要忘记使用RemoveHandler theButton.Click, AddressOf Me.Button_Click
  • 如果您使用AddHandler theButton.Click, AddressOf Me.theButton_Click 可能会更清楚,因为这将遵循默认命名约定。或者你可以称它为Me.HandlerOf_thButton_Click
【解决方案2】:

为了完善 Reed 的答案,您可以从 Form 或其他容器中获取 Button 对象并添加处理程序,或者您可以通过编程方式创建 Button 对象。
如果您从Form 或其他容器中获取Button 对象,则可以遍历Form 或其他容器控件的Controls 集合,例如PanelFlowLayoutPanel 等。然后,您可以使用
AddHandler ctrl.Click, AddressOf Me.Button_Click(变量如下面的代码)添加点击处理程序,
但我更喜欢检查Control 的类型并转换为Button,因为我不会为容器中的任何其他控件(例如标签)添加点击处理程序。请记住,此时您可以使用AddHandlerButton 的任何事件添加处理程序。
或者,您可以通过编程方式创建 Button 对象,如下面的第二个代码块所示。
然后,当然,您必须编写处理程序方法,如下面的第三个代码块。

这是一个使用Form 作为容器的示例,但您最好使用Panel 或其他一些容器控件。

Dim btn as Button = Nothing
For Each ctrl As Control in myForm.Controls
    If TypeOf ctrl Is Button Then
        btn = DirectCast(ctrl, Button)
        AddHandler btn.Click, AddressOf Me.Button_Click   ' From answer by Reed.
    End If
 Next

或者以编程方式创建Buttons,这次添加到Panel 容器。

Dim Panel1 As new Panel()
For i As Integer = 1 to 100
    btn = New Button()
    ' Set Button properties or call a method to do so.
    Panel1.Controls.Add(btn)  ' Add Button to the container.
    AddHandler btn.Click, AddressOf Me.Button_Click   ' Again from the answer by Reed.
Next

然后你的处理程序将看起来像这样

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    ' Handle your Button clicks here
End Sub

【讨论】:

    【解决方案3】:

    @Debasish Sahu,您的回答是对另一个问题的回答,即:当有几个控件的公共处理程序时,如何知道单击了哪个按钮(或任何其他控件)?所以我给出了这个问题的答案,我通常是怎么做的,几乎和你的一样,但请注意,当它处理相同类型的控件时,它也可以在没有类型转换的情况下工作:

    Private Sub btn_done_clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim selectedBtn As Button = sender
        MsgBox("you have clicked button " & selectedBtn.Name)
    End Sub
    

    【讨论】:

      【解决方案4】:

      我需要一个通用的事件处理程序,我可以在其中显示从哪个按钮调用它而无需使用 switch case...并像这样完成..

        Private Sub btn_done_clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
      
          MsgBox.Show("you have clicked button " & CType(CType(sender,  _
          System.Windows.Forms.Button).Tag, String))
      
        End Sub
      

      【讨论】:

      • 那么你还需要为每个按钮分配Tag。你可以得到一个Name 代替。好处是Name 唯一标识一个控件,而Tag 值可以重复。
      【解决方案5】:

      这个问题的变体的一些代码。使用上面的代码让我得到了我需要的点击事件,但是我被困在试图找出哪个按钮被点击了。 我的情况是我有动态数量的标签页。每个标签页上都有(全部是动态创建的)2 个图表、2 个 DGV 和一对单选按钮。每个控件都有一个相对于选项卡的唯一名称,但如果我有 20 个选项卡页,则可能有 20 个具有相同名称的单选按钮。单选按钮在您可以看到的 2 个图表和 DGV 之间切换。以下是检查其中一个单选按钮时的代码(有一个几乎相同的块将图表和 DGV 交换回来):

         Private Sub radioFit_Components_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
      
          If sender.name = "radioFit_Components" And sender.visible Then
              If sender.checked Then
                  For Each ctrl As Control In TabControl1.SelectedTab.Controls
                      Select Case ctrl.Name
                          Case "embChartSSE_Components"
                              ctrl.BringToFront()
                          Case "embChartSSE_Fit_Curve"
                              ctrl.SendToBack()
                          Case "dgvFit_Components"
                              ctrl.BringToFront()
                      End Select
                  Next
      
              End If
          End If
      
      End Sub
      

      此代码将针对任何标签页触发,并在任何标签页上交换图表和 DGV。 sender.visible 检查是在创建表单时停止代码触发。

      【讨论】:

        猜你喜欢
        • 2018-12-20
        • 2014-04-07
        • 1970-01-01
        • 2012-08-17
        • 1970-01-01
        • 2017-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多