Inserire controlli a runtime e assegnare eventi

di il
12 risposte

Inserire controlli a runtime e assegnare eventi

Ciao a tutti.
Dopo mille prove sono riuscito a inserire su un form 4 pulsanti indicizzati Pulsante_Indicizzato(i) creandoli tramite un altro pulsante Button_Crea_4_Pls_Index.
Poi avevo bisogno di assegnare una diversa azione al click per ognuno dei pulsanti creati.
Ecco ... su questo punto stò sbattendo la testa.
Riesco solo a creare la stessa azione su qualsiasi pulsante clicco.
Io vorrei ad esempio che se clicco il Pulsante_Indicizzato(2) su una label Label4 venisse scritto "Indice = 2"
Sotto metto il codice.
Dove sbaglio? Vi prego se possibile un esempio, forse è proprio tramite l'esempio che riesco a capire meglio.
Grazie 1000
Public Class Form1
    'Pulsanti indicizzati
    Dim Pulsante_Indicizzato(4) As Button
    Dim i As Integer

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

    End Sub

    Private Sub Button_Crea_4_Pls_Index_Click(sender As Object, e As EventArgs) Handles Button_Crea_4_Pls_Index.Click


        ' un ciclo for per creare i 4 pulsanti indicizzati
        For i = 1 To 4
            Pulsante_Indicizzato(i) = New Button
            Me.Controls.Add(Pulsante_Indicizzato(i))
            AddHandler Pulsante_Indicizzato(i).Click, AddressOf Pulsante_Indicizzato_Click
        Next
        'poi uno per uno li piazzo, scrivo il testo etc etc......
        Pulsante_Indicizzato(1).Top = 100
        Pulsante_Indicizzato(1).Left = 360
        Pulsante_Indicizzato(1).Width = 180
        Pulsante_Indicizzato(1).Text = "Pulsante_Indicizzato(1)"
        Pulsante_Indicizzato(1).Parent = Me
        Pulsante_Indicizzato(1).BringToFront()


        Pulsante_Indicizzato(2).Top = 130
        Pulsante_Indicizzato(2).Left = 360
        Pulsante_Indicizzato(2).Width = 180
        Pulsante_Indicizzato(2).Text = "Pulsante_Indicizzato(2)"
        Pulsante_Indicizzato(2).Parent = Me
        Pulsante_Indicizzato(2).BringToFront()


        Pulsante_Indicizzato(3).Top = 160
        Pulsante_Indicizzato(3).Left = 360
        Pulsante_Indicizzato(3).Width = 180
        Pulsante_Indicizzato(3).Text = "Pulsante_Indicizzato(3)"
        Pulsante_Indicizzato(3).Parent = Me


        Pulsante_Indicizzato(3).BringToFront()
        Pulsante_Indicizzato(4).Top = 190
        Pulsante_Indicizzato(4).Left = 360
        Pulsante_Indicizzato(4).Width = 180
        Pulsante_Indicizzato(4).Text = "Pulsante_Indicizzato(4)"
        Pulsante_Indicizzato(4).Parent = Me
        Pulsante_Indicizzato(4).BringToFront()
    End Sub


    Private Sub Pulsante_Indicizzato_Click()
        Beep()
        Label4.Text = ???? ' L'indice del Pulsante_Indicizzato() cliccato
    End Sub






End Class

12 Risposte

  • Re: Inserire controlli a runtime e assegnare eventi

    E' un approccio un po' in stile VB6. Ti consiglierei di non creare l'array di buttons, ma di assegnare un nome diverso a ciascun pulsante, es. Pulsante1, Pulsante2 ...
    Poi fai in modo che un unico evento gestisca il Click di tutti i pulsanti (Handles.....). In questa routine di gestione del click puoi interrogare il sender per capire quale pulsante è.
  • Re: Inserire controlli a runtime e assegnare eventi

    Io creerei una nuova classe che eredita da Button e aggiungerei la proprietà Indice. Poi come dice grumpy, casto il Sender e ottengo la proprietà.
  • Re: Inserire controlli a runtime e assegnare eventi

    grumpy ha scritto:


    E' un approccio un po' in stile VB6. Ti consiglierei di non creare l'array di buttons, ma di assegnare un nome diverso a ciascun pulsante, es. Pulsante1, Pulsante2 ...
    E' molto più comodo (e anche più efficiente) accedere a un array tramite l'indice numerico che ne indica la posizione, piuttosto che usare quel valore per comporre una nome in formato stringa e doverlo poi cercare appunto per nome.

    superciuck ha scritto:


    Poi avevo bisogno di assegnare una diversa azione al click per ognuno dei pulsanti creati.
    Come ti è stato suggerito, assegni a ciascun pulsante lo stesso metodo per la gestione dell'evento Click: puoi usare il parametro Sender per identificare qual è il pulsante che l'utente ha premuto, castando al tipo Button se devi accedere a proprietà specifiche dello stesso.

    Per sapere qual è la sua posizione nell'array originale in cui hai memorizzato i riferimenti ai pulsanti creati, puoi usare tranquillamente , oppure sfruttare la proprietà Tag del controllo per dati custom a tuo piacimento, oppure ancora (ma è una soluzione più complessa) usare l'altra soluzione già suggerita, ossia sfruttare la OOP, ereditare il Button creandone uno personalizzato con tutte le proprietà che ti servono.

    Ciao!
  • Re: Inserire controlli a runtime e assegnare eventi

    Si... In effetti se è solo una proprietà e Tag non è già usata, vince rispetto alla classe derivata.
    Andavo subito a complicarmi la vita.
  • Re: Inserire controlli a runtime e assegnare eventi

    Variante senza nemmeno l'array:
        Private Sub Button_Crea_4_Pls_Index_Click(sender As Object, e As EventArgs) Handles Button_Crea_4_Pls_Index.Click
            ' un ciclo for per creare i 4 pulsanti indicizzati
            For i As Byte = 0 To 3
                Dim b As Button
                b = New Button
                b.Top = 70 + 30 * (i + 1)
                b.Left = 360
                b.Width = 180
                b.Text = "Pulsante_Indicizzato(" & i + 1 & ")"
                b.Parent = Me
                b.BringToFront()
    
                Me.Controls.Add(b)
                AddHandler b.Click, AddressOf Pulsante_Indicizzato_Click
            Next
        End Sub
        Private Sub Pulsante_Indicizzato_Click(sender As Object, e As EventArgs)
            Beep()
            Label4.Text = DirectCast(sender, Button).Text.Substring(21, 1)
        End Sub
  • Re: Inserire controlli a runtime e assegnare eventi

    Ciao, scisa eh... ma se sai come sono i Pulsanti, se sai dove vanno etc.... creali subito poi mediante la proprietà Visible = True o False li mostri o meno.... ovviamente ogni Pulsante ha già la sua classe e il suo codice, si tratta solo di mostrarli o meno... non capisco perchè tutto questo sbattimento....

    P.S. non dico sia sbagliato.... dico che non capisco....
  • Re: Inserire controlli a runtime e assegnare eventi

    @orione...ed è giusto...molte volte dietro uno Snippet di richiesta d'aiuto, può nascondersi un progetto grosso come una casa, che l'utente quasi sempre rimane sul vago su cio' che gli serve e su quello che effettivamente vuole fare. ogni risposta è ben accetta, l'importante è trovare una soluzione a qualsiasi quesito.
  • Re: Inserire controlli a runtime e assegnare eventi

    Alka ha scritto:


    ... piuttosto che usare quel valore per comporre una nome in formato stringa e doverlo poi cercare appunto per nome.
    Mai detto questo. "sender.name" è il nome del pulsante, non c'è da comporre niente.

    Comunque, se come dice superciuck

    superciuck ha scritto:


    Poi avevo bisogno di assegnare una diversa azione al click per ognuno dei pulsanti creati.
    non vedo perché non si possa tornare alla "normalità" creando gestori di evento distinti per ogni pulsante e, se c' è del codice comune, inserirlo in una Sub/Function separata.

    Ciao!
    [/quote]
  • Re: Inserire controlli a runtime e assegnare eventi

    grumpy ha scritto:


    Mai detto questo. "sender.name" è il nome del pulsante, non c'è da comporre niente.
    Personalmente, preferisco una soluzione che non si basi sul fatto che il pulsante debba necessariamente avere un nome, e che questo nome non debba avere un formato particolare da ricordarsi, né una logica indispensabile per estrarre l'informazione che serve (quale pulsante).

    Tutto qui.

    Magari mi sono espresso male: la mia era solo una preferenza per abitudine su immediatezza e sicurezza (da tipizzazione forzata), ma è appunto una mia preferenza, quindi ci sta perfettamente anche la tua nel quadro generale.

    grumpy ha scritto:


    non vedo perché non si possa tornare alla "normalità" creando gestori di evento distinti per ogni pulsante e, se c' è del codice comune, inserirlo in una Sub/Function separata.
    Diciamo che manca qualche info su ciò che specificatamente devono fare questi pulsanti, e sul perché siano creati a runtime.

    Io ho preso il tutto come "a titolo di esempio": laddove i pulsanti creati a runtime sono 6 io ne ho intesi potenzialmente 1.000, e laddove le azioni sono "distinte" io ne ho intesa una con parametrizzazione in base al pulsante, però è possibile che lo scenario sia diverso e si stia effettivamente facendo della fatica inutile.
  • Re: Inserire controlli a runtime e assegnare eventi

    Bhèèèè che dire?
    Anzitutto grazie a tutti davvero......
    Oggi ho dei problemini a far partire il PC dove stò lavorando al problema sopra.
    Questo è solo per ringraziare e provare a spiegare il perchè dei pulsanti indicizzati.
    In futuro dovrò effettuare delle misure con uno spettrofotometro su dei campioni di colore.
    Poi devo riportare le misure su un grafico colore CIE 1931, saranno tutte misure x, y.
    Circa credo 60-90 letture da riportare sul grafico.
    Pensavo quindi di creare 60-90 pulsanti indicizzati ognuno dei quali corrisponde ad una misura,
    quando ci clicchi, oppure ci vai sopra con il mouse appaiono coordinate x,y data misura, campione etc etc...
    I dati saranno presi da un file excel credo.
    Per cui non è obbligatorio che le 90 misure siano 90 pulsanti, potrebbero essere anche 90 picturebox molto piccole con l'immagine di un mirino, o altro.
    Insomma pensavo ai pulsanti solo come esempio. Poi credo che il discorso possa valere per altri oggetti...
    Appena parte il PC ricomincio a dare un occhio.
    Per ora davvero Grazie.
  • Re: Inserire controlli a runtime e assegnare eventi

    Dunque.... ho fatto così funziona.....
    Anzitutto ho creato 20 pulsanti (volevo vedere se funziona con indici maggiori di 9 ... a 2 cifre insomma). All'interno del ciclo do un nome ad ogni pulsante e lo piazzo in posizione.
    Nella sub di gestione dei pulsanti creati adopero il sender per riconoscere il nome del pulsante (che poi è uguale all'indice) poi conversione da string ad integer e adopero l'indice (adeso conosciuto) per scrivere le coordinate del pulsante cliccato.
    Public Class Form1
        Dim Pulsante_Indicizzato(20) As Button
        Dim nome_puls_String As String
        Dim indice_String As String
        Dim indice_Int As Integer
    
        Private Sub Button_Crea_20_Pls_Index_Click(sender As Object, e As EventArgs) Handles Button_Crea_20_Pls_Index.Click
            For i = 1 To 20
                Pulsante_Indicizzato(i) = New Button
                nome_puls_String = CType(i, String)
                Pulsante_Indicizzato(i).Name = nome_puls_String
    
                Pulsante_Indicizzato(i).Top = 10 + (i * 22)
                Pulsante_Indicizzato(i).Left = 10 + (i * 24)
                Pulsante_Indicizzato(i).Width = 100
                Pulsante_Indicizzato(i).Text = nome_puls_String
                Pulsante_Indicizzato(i).Parent = Me
                Pulsante_Indicizzato(i).BringToFront()
    
                Me.Controls.Add(Pulsante_Indicizzato(i))
                AddHandler Pulsante_Indicizzato(i).Click, AddressOf Pulsante_Indicizzato_Click
                AddHandler Pulsante_Indicizzato(i).MouseHover, AddressOf Pulsante_Indicizzato_MouseHover
            Next
        End Sub
        Private Sub Pulsante_Indicizzato_Click(sender As Object, e As EventArgs)
            'Beep()
            indice_String = sender.Name
            Label1.Text = indice_String  ' L'indice del Pulsante_Indicizzato() cliccato
            indice_Int = CType(indice_String, Integer)
            Label2.Text = indice_Int
            Label3.Text = Pulsante_Indicizzato(indice_Int).Top
            Label4.Text = Pulsante_Indicizzato(indice_Int).Left
    
        End Sub
        Private Sub Pulsante_Indicizzato_MouseHover(sender As Object, e As EventArgs)
            'Beep()
            indice_String = sender.Name
            Label1.Text = indice_String  ' L'indice del Pulsante_Indicizzato() cliccato
            indice_Int = CType(indice_String, Integer)
            Label2.Text = indice_Int
            Label3.Text = Pulsante_Indicizzato(indice_Int).Top
            Label4.Text = Pulsante_Indicizzato(indice_Int).Left
        End Sub
    
    End Class
  • Re: Inserire controlli a runtime e assegnare eventi

    Vista l'evoluzione della discussione, la mia idea di una classe derivata da Button (o un altro controllo a scelta) non è più tanto campata per aria...
    Potresti impostare come proprietà l'indice e le misurazioni direttamente nel nuovo oggetto, senza andare a fare poi ricerche a ritroso in un secondo momento.
Devi accedere o registrarti per scrivere nel forum
12 risposte