+ Rispondi al messaggio
Visualizzazione dei risultati da 1 a 5 su 5

Treeview popolato da tabella

  1. #1
    Post
    39
    Like Inviati  
    0
    Like Ricevuti  
    0
    Ciao a tutti.
    Io ho una tabella di nome <helper> con questi campi:
    0 key (long) che rappresenta la name del nodo
    1 titolo (text 255) che rappresenta la text del nodo
    2 key_rif (long) che rappresenta la name del nodo del quale questo nodo è child (per esempio se il valore è 7 vuol dire che questo nodo è child del nodo denominato 7)

    Devo popolare una TreeView dalla tabella e ho scritto questo codice:
        Private Function bCaricaTreeView1(ByVal sStrSQL As String) As DataTable
            Dim dt As New DataTable
            Dim sConnTV As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = c:\helper\ark.accdb"
            Using con As New OleDbConnection(sConnTV)
                Using cmd As New OleDbCommand(sStrSQL)
                    Using sda As New OleDbDataAdapter()
                        cmd.CommandType = CommandType.Text
                        cmd.Connection = con
                        sda.SelectCommand = cmd
                        sda.Fill(dt)
                    End Using
                End Using
                Return dt
            End Using
        End Function
    
        Private Sub ptreeview(sDtParent As DataTable, sParentID As Integer, tn1 As TreeNode)
            For Each row As DataRow In sDtParent.Rows
                Dim tnChild As New TreeNode() With {
                    .Text = row("titolo").ToString(),
                    .Name = row("key")
                }
                If sParentID = 0 Then
                    TreeView1.Nodes.Add(tnChild)
                    Dim dtChild As DataTable = Me.bCaricaTreeView1("SELECT key, titolo FROM helper WHERE key_rif = " & tnChild.Name)
                    ptreeview(dtchild, Convert.ToInt32(tnChild.Name), tnChild)
                Else
                    tn1.Nodes.Add(tnChild)
                End If
                If Val(tnChild.Name) > lKey Then
                    lKey = Val(tnChild.Name)
                End If
            Next
        End Sub
    
    Quando devo popolare scrivo:
            Dim dt As DataTable = Me.bCaricaTreeView1("SELECT key, titolo FROM helper WHERE key_rif = 0")
            Me.ptreeview(dt, 0, Nothing)
    
    Funziona tutto molto bene fino a che i livelli dei nodi sono 2 (principale e child) se devo creare un child di child non va più bene e non lo inserisce nella TreeView.
    Dove sbaglio?

  2. #2
    Sgrubak non è in linea Scribacchino
    Post
    539
    Like Inviati  
    9
    Like Ricevuti  
    3
    Quote Originariamente inviato da Taurus dei miracoli Visualizza il messaggio
    Dove sbaglio?
    Perché inneschi la ricorsione solo se [sParentId] è 0?
    '...
    If sParentID = 0 Then
        TreeView1.Nodes.Add(tnChild)
        Dim dtChild As DataTable = Me.bCaricaTreeView1("SELECT key, titolo FROM helper WHERE key_rif = " & tnChild.Name)
        ptreeview(dtchild, Convert.ToInt32(tnChild.Name), tnChild)
    Else
       '...
    
    Io sposterei la chiamata ricorsiva fuori dall'If, ed imposterei come condizione di uscita per la funzione, il fatto che la Select per quel preciso Id padre, restituisce una tabella vuota. Così verifica sempre se sono presenti righe per quel [key_rif], indipendentemente dall'annidamento a cui sei arrivato.

    EDIT: Personalmente, eviterei di interrogare il DB ad ogni cambio di [sParentId]. Eseguirei la query una volta sola, prelevando tutto e popolando una sola tabella. Dopo di che, userei il metodo Select per filtrare solo le righe con il [key_rif] che mi interessa. Così da non effettuare tante query una dietro l'altra...
    Ultima modifica di Sgrubak; 27-11-2020 18:26 

  3. #3
    Post
    39
    Like Inviati  
    0
    Like Ricevuti  
    0
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Perché inneschi la ricorsione solo se [sParentId] è 0?
    Con sParentId = 0 io avevo, in modo corretto tutti i valori padre e tutti i child di primo livello.
    Quello che non ho capito è come fare in modo di dirgli: man mano che vai avanti trova tutti i figli (senza riscriverli dopo a livello di padre).

  4. #4
    Sgrubak non è in linea Scribacchino
    Post
    539
    Like Inviati  
    9
    Like Ricevuti  
    3
    Quote Originariamente inviato da Taurus dei miracoli Visualizza il messaggio
    Con sParentId = 0 io avevo, in modo corretto tutti i valori padre e tutti i child di primo livello...
    E questo è pacifico.

    Io suggerivo di andare in quest'ordine:
    1) Caricherei in [dt] direttamente tutti i record
    SELECT key, titolo FROM helper --Senza la clausola where
    
    2) Modificherei la funzione ricorsiva così:
        Private Sub ptreeview(rigaFiglio As DataRow, Optional tn1 As TreeNode = Nothing)
            'Creo il nodo partendo dalla riga
            Dim tnChild As New TreeNode() With {
                    .Text = rigaFiglio("titolo").ToString(),
                    .Name = rigaFiglio("key")
                }
    
            'Decido dove aggiungere il nodo
            If tn1 Is Nothing Then
                TreeView1.Nodes.Add(tnChild)
            Else
                tn1.Nodes.Add(tnChild)
            End If
    
            'Prelevo tutti i sotto nodi
            Dim subChilds As DataRow() = dt.Select("key_rif = " & rigaFiglio("key").ToString)
    
            'Se non ci sono sottonodi, esco altrimenti innesco la ricorsione
            If (subChilds.Length = 0) Then
                Exit Sub
            Else
                For Each sottofiglio In subChilds
                    ptreeview(sottofiglio, tnChild)
                Next
            End If
    
                If Val(tnChild.Name) > lKey Then
                    lKey = Val(tnChild.Name)
                End If
            Next
        End Sub
    
    Ho solo abbozzato, non ho provato. Ma la logica c'è... Ti ho lasciato anche i commenti per chiarire meglio quel che intendo. Spero ti sia di aiuto

    P.S: non vedo dove apri la connessione al DB... Non c'entra nulla, ma è curioso che funzioni...

  5. #5
    Post
    39
    Like Inviati  
    0
    Like Ricevuti  
    0
    Grazie Sgrubak,
    oggi provo e poi ti dico, anche perchè così possiamo essere utili a tutti.

+ Rispondi al messaggio

Potrebbero interessarti anche ...

  1. Reportviewer popolato dinamicamente.
    Da massimo74rn nel forum Visual Basic .Net
    Risposte: 3
    Ultimo Post: 30-06-2011, 02:08
  2. ComboBox popolato a due valori
    Da lelo74 nel forum Visual Basic .Net
    Risposte: 4
    Ultimo Post: 21-04-2006, 09:16
  3. TreeView
    Da Vanessa nel forum Visual Basic 6
    Risposte: 2
    Ultimo Post: 18-04-2006, 11:55
  4. Treeview
    Da simo_79 nel forum Microsoft Word
    Risposte: 1
    Ultimo Post: 31-05-2005, 19:54
  5. icone al TreeView
    Da Carbonara nel forum Visual Basic .Net
    Risposte: 5
    Ultimo Post: 25-09-2004, 10:18