[vb.net] Dynamic button click event handler

I've 100 buttons created dynamically in a form. How can I an add event handler to them?

This question is related to vb.net

The answer is


I needed a common event handler in which I can show from which button it is called without using switch case... and done like this..

  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

You can use AddHandler to add a handler for any event.

For example, this might be:

AddHandler theButton.Click, AddressOf Me.theButton_Click

Some code for a variation on this problem. Using the above code got me my click events as needed, but I was then stuck trying to work out which button had been clicked. My scenario is I have a dynamic amount of tab pages. On each tab page are (all dynamically created) 2 charts, 2 DGVs and a pair of radio buttons. Each control has a unique name relative to the tab, but there could be 20 radio buttons with the same name if I had 20 tab pages. The radio buttons switch between which of the 2 graphs and DGVs you get to see. Here is the code for when one of the radio buttons gets checked (There's a nearly identical block that swaps the charts and DGVs back):

   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

This code will fire for any of the tab pages and swap the charts and DGVs over on any of the tab pages. The sender.visible check is to stop the code firing when the form is being created.


@Debasish Sahu, your answer is an answer to another question, namely: how to know which button (or any other control) was clicked when there is a common handler for a couple of controls? So I'm giving an answer to this question how I usually do it, almost the same as yours, but note that also works without type conversion when it handles the same type of Controls:

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

Just to round out Reed's answer, you can either get the Button objects from the Form or other container and add the handler, or you could create the Button objects programmatically.
If you get the Button objects from the Form or other container, then you can iterate over the Controls collection of the Form or other container control, such as Panel or FlowLayoutPanel and so on. You can then just add the click handler with
AddHandler ctrl.Click, AddressOf Me.Button_Click (variables as in the code below),
but I prefer to check the type of the Control and cast to a Button so as I'm not adding click handlers for any other controls in the container (such as Labels). Remember that you can add handlers for any event of the Button at this point using AddHandler.
Alternatively, you can create the Button objects programmatically, as in the second block of code below.
Then, of course, you have to write the handler method, as in the third code block below.

Here is an example using Form as the container, but you're probably better off using a Panel or some other container control.

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

Alternatively creating the Buttons programmatically, this time adding to a Panel container.

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

Then your handler will look something like this

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