none
LABEL() Index RRS feed

  • Domanda

  • Ciao a tutti ho visto molti che han avuto il mio stesso problema ,

    venendo da VB6 gli index dei controlli.

    Qualcuno riesce a spiegare bene come posso fare questo che era semplice in vb6 (ora vb net 2019 )


                For Each section In data.Sections

                    Dim I
                    If I > 101 Then Exit Sub
                    X = data.Sections.Count



                    Dim sNome = Ges.IniRead(tPath, section.SectionName, "Nome")
                    Dim sPing = Ges.IniRead(tPath, section.SectionName, "Ping")
                    Dim Acc_Name = section.SectionName

                    Dim L(I) As New Label
                    L(I) = Label()
                    Debug.Print(I)
                    L(I).Text = "ma ciaoooooooooooo"

    eccc... ve ne sarei molto grato, e se magari in zona vi offro volentieri una birra !

    Grazie a tutti 


    Paolo Spagnolo

    domenica 17 maggio 2020 08:55

Risposte

  • Ciao,

    oltre alle ottime risposte che ti sono state date, ti potrei anche indicare una alternativa.

    Puoi "simulare" la creazione di una matrice di controlli semplicemente assegnando ai vari controlli, il nome formato da un prefisso ed il numero che indicherebbe la matrice.

    Esattamente come fa l'IDE, che crea, se parliamo di Label, Label1, Label2... LabelN, tu potresti disegnare (in DesignTime, quindi) le 300 label che si chiamano A0, A1... A299 (vedi tu se le vuoi "base" 0 o 1)

    Quando devi andare ad agire su una label, la cerchi nella form usando il metodo Find della ControlCollection della form stessa.

    Una cosa come (se il prefisso è Label)

    Private Function CercaLabel(ByVal Indice As Integer) As Control
            Dim ctrl As Control
            Dim name As String = "Label" & Indice.ToString
            Dim ctrls = Me.Controls.Find(name, True)
            If ctrls.Count = 1 Then ctrl = ctrls(0)
            Return ctrl
        End Function

    lunedì 18 maggio 2020 09:20
  • Interessante, si potrebbe generalizzare con

          Private Function CercaControl(ByVal Indice As Integer, ByVal controllo As String) As Control
            Dim ctrl As Control
            Dim name As String = controllo & Indice.ToString
            Dim ctrls = Me.Controls.Find(name, True)
            If ctrls.Count = 1 Then ctrl = ctrls(0)
            Return ctrl
        End Function

    lunedì 18 maggio 2020 11:49
  • Le matrici di controlli esistono ancora ma puoi soltanto crearle runtime e non puoi crearle nella progettazione del form dall'ide. Questo ha come conseguenza il fatto che non puoi, come facevi prima, inserire i controlli e vederli in progettazione ma puoi (con le procedure spiegate in quel link) creare un panel e poi creare runtime la matrice dentro il panel ed "immaginare" in progettazione che conterrà quelle label.

    Ovviamente è solo un esempio, puoi crearli dove ti pare, suggerisco il panel solo per una disposizione ordinata.

    Ti va bene anche che devi soltanto scrivere il testo, senza gestire eventi come click o doppio click, altrimenti le cose si complicano leggermente, specialmente su 300 label.

    In alternativa, potresti anche seguire altre vie ma sono più utili quando devi gestirne di meno, 300 label sono tante, ma ti indico alcune cose che talvolta ho fatto.

    Come troverai scritto lì, puoi creare le label in modo da vederle anche in progettazione e dopo infilarle tutte in una matrice, così avresti un approccio misto fra quello antico e quello che prevede la creazione a runtime. Puoi anche usare il nome di ogni label per decidere se metterla in una matrice ed in quale matrice metterla. Interessante.

    Altra possibilità: potresti lasciar perdere la matrice e lavorare in altra maniera, puoi usare la proprietà "tag" delle label come se fosse il vecchio indice, fare un for each sulle label ed agire in base a questo tag.

    Se hai otto label, label1, label2, ... , label8 nel panel3 puoi mettere il tag "1" a label1, il tag "2" a label2, … , il tag "8" a label8. A questo punto ti crei una sub che ti scrive il testo cosa nella label dove in questo modo

    sub scrivi(byval dove as integer, cosa as string)
     for each l as control in panel3.controls
      if typeof(l) is label and l.tag <>"" then
        dim indi as integer = ctype(l.tag,integer)
        if indi = dove then
           l.text = cosa
           exit for
        end if
      end if
     next
    
    end sub

    (l'ho scritto al volo, andrebbe sistemato un po' ma era per mostrare cosa intendevo)

    Però con 300 label ci vuole tanta pazienza.

    Io piano piano sono riuscito a dimenticare i vecchi metodi che adoperavo ed usare quelli nuovi senza ricorrere a varie simulazioni.

    lunedì 18 maggio 2020 07:23
  • Io avrei compattato leggermente la creazione della matrice, con una riga di Linq, in questo modo:

    Dim cl = From l In contenit.Controls.OfType(Of Label)
                     Select l Where l.Tag Is Nothing OrElse l.Tag.ToString <> "SKIP"
            Return cl.ToArray

    Due cosette al volo.

    Dalla verifica che fai sul Tag, posso intuire che non utilizzi l'opzione Strict impostata ad On. Ti consiglio vivamente di impostare Strict ad On, che magari ti fa scrivere mezza riga di codice in più, ma ti salva da errori subdoli.

    Visto che utilizzi AddHandler, ricordati sempre che devi prevedere anche l'utilizzo di RemoveHandler, visto che una fonte abbastanza rognosa di problemi può essere il lasciar in giro dei gestori di eventi quando non dovrebbero più esistere.

    giovedì 21 maggio 2020 22:34
  • Buona idea, siamo in attesa dei tuoi sviluppi

    Qualcosa come

    Function matricizzalabel(ByVal contenit As Control) As Label()
            Dim cl As New List(Of Label)
            For Each l As Label In contenit.Controls.OfType(Of Label)
                If l.Tag.ToString <> "SKIP" Then
                    cl.Add(l)
                End If
            Next
            If cl.Count > 0 Then
                Dim lbls() As Label = cl.ToArray
                For i As Integer = 0 To UBound(lbls)
                    AddHandler lbls(i).Click, AddressOf qualcosa
                Next
                Return lbls
            Else
                Return Nothing
            End If
    End Function

    dove

    Private Sub qualcosa(sender As Object, e As EventArgs)
            Dim l As Label = sender
            TextBox6.AppendText("Saluto " + l.Name + vbCrLf)
    End Sub

    con

    TextBox6.Clear()
    Dim labpan1() As Label = matricizzalabel(Panel1)
    If labpan1 IsNot Nothing Then
                TextBox6.AppendText("Trovati " + labpan1.Count.ToString + " elementi" + vbCrLf)
                For i As Integer = 0 To UBound(labpan1)
                    TextBox6.AppendText(i.ToString + " " + labpan1(i).Name + vbCrLf)
                Next
    Else
                TextBox6.AppendText("Nessun elemento trovato" + vbCrLf)
    End If


    giovedì 21 maggio 2020 06:51
  • Hai ragione, strict era su off (lo avevo aggiunto ad un progetto che utilizzo genericamente per fare cose "al volo").

    Ho messo il tostring al tag.

    Per il resto, concordo pienamente con le tue osservazioni.

    P.S. (edit):

    Si tratta di una cosa ancora da sistemare, ordinando gli elementi della matrice in modo più comodo ed altro.

    venerdì 22 maggio 2020 06:48

Tutte le risposte

  • Non ho capito il problema, forse questo link ti può aiutare

    https://stackoverflow.com/questions/5299435/how-to-create-control-arrays-in-vb-net


    • Modificato patel45 domenica 17 maggio 2020 14:09
    domenica 17 maggio 2020 09:05
  • Grazie Patel della Risposta.

    IN pratica ho un form con 300 label al ciclo le aggiorno nel text con i ping che arrivano in file *ini .

    ho poi nominato tre tipi di label a() p() l() 

    quando nel file *ini vedo il ping su un dato computer memorizzato li modifico la label 

    con A(5)   esempio A(5).TEXT = "08:00.55 - 17-05-2020"  

    spero di essere stato chiaro nel frattempo guardo il link 

    Paolo


    Paolo Spagnolo


    domenica 17 maggio 2020 09:29
  • Le matrici di controlli esistono ancora ma puoi soltanto crearle runtime e non puoi crearle nella progettazione del form dall'ide. Questo ha come conseguenza il fatto che non puoi, come facevi prima, inserire i controlli e vederli in progettazione ma puoi (con le procedure spiegate in quel link) creare un panel e poi creare runtime la matrice dentro il panel ed "immaginare" in progettazione che conterrà quelle label.

    Ovviamente è solo un esempio, puoi crearli dove ti pare, suggerisco il panel solo per una disposizione ordinata.

    Ti va bene anche che devi soltanto scrivere il testo, senza gestire eventi come click o doppio click, altrimenti le cose si complicano leggermente, specialmente su 300 label.

    In alternativa, potresti anche seguire altre vie ma sono più utili quando devi gestirne di meno, 300 label sono tante, ma ti indico alcune cose che talvolta ho fatto.

    Come troverai scritto lì, puoi creare le label in modo da vederle anche in progettazione e dopo infilarle tutte in una matrice, così avresti un approccio misto fra quello antico e quello che prevede la creazione a runtime. Puoi anche usare il nome di ogni label per decidere se metterla in una matrice ed in quale matrice metterla. Interessante.

    Altra possibilità: potresti lasciar perdere la matrice e lavorare in altra maniera, puoi usare la proprietà "tag" delle label come se fosse il vecchio indice, fare un for each sulle label ed agire in base a questo tag.

    Se hai otto label, label1, label2, ... , label8 nel panel3 puoi mettere il tag "1" a label1, il tag "2" a label2, … , il tag "8" a label8. A questo punto ti crei una sub che ti scrive il testo cosa nella label dove in questo modo

    sub scrivi(byval dove as integer, cosa as string)
     for each l as control in panel3.controls
      if typeof(l) is label and l.tag <>"" then
        dim indi as integer = ctype(l.tag,integer)
        if indi = dove then
           l.text = cosa
           exit for
        end if
      end if
     next
    
    end sub

    (l'ho scritto al volo, andrebbe sistemato un po' ma era per mostrare cosa intendevo)

    Però con 300 label ci vuole tanta pazienza.

    Io piano piano sono riuscito a dimenticare i vecchi metodi che adoperavo ed usare quelli nuovi senza ricorrere a varie simulazioni.

    lunedì 18 maggio 2020 07:23
  • Ciao,

    oltre alle ottime risposte che ti sono state date, ti potrei anche indicare una alternativa.

    Puoi "simulare" la creazione di una matrice di controlli semplicemente assegnando ai vari controlli, il nome formato da un prefisso ed il numero che indicherebbe la matrice.

    Esattamente come fa l'IDE, che crea, se parliamo di Label, Label1, Label2... LabelN, tu potresti disegnare (in DesignTime, quindi) le 300 label che si chiamano A0, A1... A299 (vedi tu se le vuoi "base" 0 o 1)

    Quando devi andare ad agire su una label, la cerchi nella form usando il metodo Find della ControlCollection della form stessa.

    Una cosa come (se il prefisso è Label)

    Private Function CercaLabel(ByVal Indice As Integer) As Control
            Dim ctrl As Control
            Dim name As String = "Label" & Indice.ToString
            Dim ctrls = Me.Controls.Find(name, True)
            If ctrls.Count = 1 Then ctrl = ctrls(0)
            Return ctrl
        End Function

    lunedì 18 maggio 2020 09:20
  • Interessante, si potrebbe generalizzare con

          Private Function CercaControl(ByVal Indice As Integer, ByVal controllo As String) As Control
            Dim ctrl As Control
            Dim name As String = controllo & Indice.ToString
            Dim ctrls = Me.Controls.Find(name, True)
            If ctrls.Count = 1 Then ctrl = ctrls(0)
            Return ctrl
        End Function

    lunedì 18 maggio 2020 11:49
  • Molto bello. Si potrebbe anche usare questa CercaControl per generare le matrici all'avvio ed aggiungere eventuali eventhandler e poi lavorare su queste matrici nella antica maniera. Se si inseriscono in appositi contenitori i controlli da matricizzare (perdonatemi il termine), si può aggiungere il contenitore alla funzione CercaControlli come optional ed inserire in una matrice tutte le label o le textbox o i button di quel contenitore, a questo punto aggiungerei un tag di "skip" per i controlli da tener fuori e ci siamo.
    martedì 19 maggio 2020 07:08
  • Buona idea, siamo in attesa dei tuoi sviluppi
    martedì 19 maggio 2020 07:17
  • Grazie della spiegazione , anche questa interessante.

    una alla volta le proverò  per capire quale si presta meglio .

    Grazie di nuovo 

    Paolo


    Paolo Spagnolo

    martedì 19 maggio 2020 16:22
  • Grazie di cuore veramente a tutti ....

    vedo di mettere in opera i consigli e speriamo bene eheheh

    GRAZIE DI NUOVO

    PAOLO


    Paolo Spagnolo

    martedì 19 maggio 2020 16:23
  • Buona idea, siamo in attesa dei tuoi sviluppi

    Qualcosa come

    Function matricizzalabel(ByVal contenit As Control) As Label()
            Dim cl As New List(Of Label)
            For Each l As Label In contenit.Controls.OfType(Of Label)
                If l.Tag.ToString <> "SKIP" Then
                    cl.Add(l)
                End If
            Next
            If cl.Count > 0 Then
                Dim lbls() As Label = cl.ToArray
                For i As Integer = 0 To UBound(lbls)
                    AddHandler lbls(i).Click, AddressOf qualcosa
                Next
                Return lbls
            Else
                Return Nothing
            End If
    End Function

    dove

    Private Sub qualcosa(sender As Object, e As EventArgs)
            Dim l As Label = sender
            TextBox6.AppendText("Saluto " + l.Name + vbCrLf)
    End Sub

    con

    TextBox6.Clear()
    Dim labpan1() As Label = matricizzalabel(Panel1)
    If labpan1 IsNot Nothing Then
                TextBox6.AppendText("Trovati " + labpan1.Count.ToString + " elementi" + vbCrLf)
                For i As Integer = 0 To UBound(labpan1)
                    TextBox6.AppendText(i.ToString + " " + labpan1(i).Name + vbCrLf)
                Next
    Else
                TextBox6.AppendText("Nessun elemento trovato" + vbCrLf)
    End If


    giovedì 21 maggio 2020 06:51
  • Ottimo lavoro Paolo, mi sarà utile.
    giovedì 21 maggio 2020 09:44
  • Io avrei compattato leggermente la creazione della matrice, con una riga di Linq, in questo modo:

    Dim cl = From l In contenit.Controls.OfType(Of Label)
                     Select l Where l.Tag Is Nothing OrElse l.Tag.ToString <> "SKIP"
            Return cl.ToArray

    Due cosette al volo.

    Dalla verifica che fai sul Tag, posso intuire che non utilizzi l'opzione Strict impostata ad On. Ti consiglio vivamente di impostare Strict ad On, che magari ti fa scrivere mezza riga di codice in più, ma ti salva da errori subdoli.

    Visto che utilizzi AddHandler, ricordati sempre che devi prevedere anche l'utilizzo di RemoveHandler, visto che una fonte abbastanza rognosa di problemi può essere il lasciar in giro dei gestori di eventi quando non dovrebbero più esistere.

    giovedì 21 maggio 2020 22:34
  • Hai ragione, strict era su off (lo avevo aggiunto ad un progetto che utilizzo genericamente per fare cose "al volo").

    Ho messo il tostring al tag.

    Per il resto, concordo pienamente con le tue osservazioni.

    P.S. (edit):

    Si tratta di una cosa ancora da sistemare, ordinando gli elementi della matrice in modo più comodo ed altro.

    venerdì 22 maggio 2020 06:48