it-swarm.it

Gestore di eventi clic pulsante dinamico

Ho 100 pulsanti creati dinamicamente in un modulo. Come posso aggiungere un gestore eventi ad essi?

27
Debasish Sahu

È possibile utilizzare AddHandler per aggiungere un gestore per qualsiasi evento.

Ad esempio, questo potrebbe essere:

AddHandler theButton.Click, AddressOf Me.theButton_Click
51
Reed Copsey

Solo per completare la risposta di Reed, puoi ottenere gli oggetti Button dal Form o un altro contenitore e aggiungere il gestore, oppure puoi creare gli oggetti Button a livello di codice.
Se ottieni gli oggetti Button dal Form o da un altro contenitore, puoi scorrere la raccolta Controls della Form o altro controllo contenitore, come Panel o FowLayoutPanel e così via. È quindi possibile aggiungere semplicemente il gestore di clic con
AddHandler ctrl.Click, AddressOf Me.Button_Click (variabili come nel codice seguente),
ma preferisco controllare il tipo di Control e trasmettere a Button in modo da non aggiungere gestori di clic per altri controlli nel contenitore (come Etichette ). Ricorda che puoi aggiungere gestori per qualsiasi evento di Button a questo punto usando AddHandler.
In alternativa puoi creare gli oggetti Button a livello di codice, come nel secondo blocco di codice qui sotto.
Quindi ovviamente devi scrivere il metodo del gestore, come nel terzo blocco di codice in basso.

Ecco un esempio usando Form come contenitore, ma probabilmente stai meglio usando Panel o qualche altro controllo contenitore.

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

In alternativa, creando Buttons a livello di codice, questa volta aggiungendo a un contenitore 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 answer by Reed.
Next

Quindi il tuo gestore sarà simile a questo

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

@Debasish Sahu, la tua risposta è una risposta a un'altra domanda, vale a dire: come sapere quale pulsante (o qualsiasi altro controllo) è stato cliccato quando c'è un gestore comune per un paio di controlli? Quindi sto dando una risposta a questa domanda su come lo faccio di solito, quasi uguale alla tua, ma nota che funziona anche senza conversione di tipo quando gestisce lo stesso tipo di controlli:

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
3
monami

Avevo bisogno di un gestore di eventi comune in cui posso mostrare da quale pulsante viene chiamato senza usare il caso switch ... e fatto così ...

  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
1
Debasish Sahu

Qualche codice per una variazione su questo problema. Usando il codice sopra ho ottenuto i miei eventi di click secondo necessità, ma poi sono stato bloccato cercando di capire quale pulsante era stato cliccato. Il mio scenario è che ho una quantità dinamica di pagine tab. Su ciascuna scheda sono (tutti creati dinamicamente) 2 grafici, 2 DGV e una coppia di pulsanti di opzione. Ogni controllo ha un nome univoco rispetto alla scheda, ma potrebbero esserci 20 pulsanti di opzione con lo stesso nome se avessi 20 schede. I pulsanti di opzione consentono di passare da uno dei 2 grafici a un DGV visualizzato. Ecco il codice per quando viene controllato uno dei pulsanti di opzione (c'è un blocco quasi identico che scambia i grafici e i DGV indietro):

   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

Questo codice viene attivato per una qualsiasi delle schede e scambia i grafici e i DGV su una qualsiasi delle schede. Il controllo sender.visible è di arrestare l'attivazione del codice durante la creazione del modulo.

0
Kristian