RISOLTO C# Creare una treeview in pivot mode da un datatable o datagridview

Pubblicità
Stato
Discussione chiusa ad ulteriori risposte.

Alimuzzy

Nuovo Utente
Messaggi
7
Reazioni
3
Ciao a tutti,
sto cercando di organizzare i nodi di una treeview con una struttura a pivot leggendo da un datatable o datagridview, ho provato vari cicli for ma non riesco
ad esempio:
tabella

tabella

column 1column 2column 3
row1.1row 1.2row 1.3
row2.1row 2.2row 2.3
row3.1row 3.2row 3.3


Pivot

Etichette di riga
row1.1
--row 1.2
----row 1.3
row2.1
--row 2.2
----ow 2.3
row3.1
--row 3.2
----row 3.3

questo e cio che ho tentato:

Codice:
for(int x=0; x < dataGridView1.Columns.Count-2; x++)
                        {
                            for (int y=0; y < dataGridView1.Rows.Count-2; y++)
                            {
                               
                                cella1Colonna = dataGridView1.Rows[y].Cells[x].Value.ToString();
                                cella2Colonna = dataGridView1.Rows[y+1].Cells[x].Value.ToString();
                                temporaneo = dataGridView1.Rows[y].Cells[x+1].Value.ToString();

                                //MessageBox.Show(cella1Colonna + ", " + cella2Colonna);

                                if (cella1Colonna.Equals(cella2Colonna))
                                {
                                    continue;
                                }
                                else
                                {
                                    //if (parent == null)
                                    //{
                                        parent = new TreeNode(cella1Colonna);
                                        treeView1.Nodes.Add(parent);
                                        temp = new TreeNode(cella2Colonna);
                                        parent.Nodes.Add(temp);
                                        //treeView1.Nodes.Add(parent);
                                        //MessageBox.Show(cella1Colonna + ", " + cella2Colonna);
                                    //}
                                }
                              
                            }
                            treeView1.Nodes.Add(parent);
                            parent = new TreeNode(cella1Colonna);

                        }
Grazie
 
Ultima modifica da un moderatore:
Scusa, ma non capisco cosa vuoi ottenere nè dalla spiegazione nè dal codice.
“Pivot” è un termine molto generico, devi spiegare quali siano le condizioni, ma in genere la visualizzazione non viene effettuata leggendo tutti i record del database uno per uno effettuando i test delle condizioni nel codice, bensì viene usata una ricerca condizionale nel database (è per quello che un database viene usato) in modo che avere i dati pronti per essere visualizzati.
 
Scusa, ma non capisco cosa vuoi ottenere nè dalla spiegazione nè dal codice.
“Pivot” è un termine molto generico, devi spiegare quali siano le condizioni, ma in genere la visualizzazione non viene effettuata leggendo tutti i record del database uno per uno effettuando i test delle condizioni nel codice, bensì viene usata una ricerca condizionale nel database (è per quello che un database viene usato) in modo che avere i dati pronti per essere visualizzati.
Ciao Andretti, perdonami se non sono stato molto chiaro, non ho molta esperienza di programmazione ad ogni modo alla fine sono riuscito a trovare una soluzione che mi ha permesso di organizzare i nodi di una treeview attingendo da un datagridview, probabilmente non sarà la soluzione ideale ma alla fine ottengo quello che volevo ottenere, di seguito il codice

Codice:
for (int row = 0; row < dataGridView1.Rows.Count - 2; row++)
                        {
                            TreeNode tNode = new TreeNode();   // Remember last node (column)

                            for (int col = 0; col < dataGridView1.Columns.Count ; col++)
                            {
                                string cell1Value = dataGridView1.Rows[row].Cells[col].Value.ToString();
                                string cell2Value = dataGridView1.Rows[row + 1].Cells[col].Value.ToString();
                              

                                //MessageBox.Show(cell1Value + ", " + cell2Value);

                                if (col == 0)   // Root/Parent Node
                                {
                                    if (cell2Value.Equals(cell1Value)) break;
                                    tNode = treeView1.Nodes.Add(cell1Value);
                                }
                                else            // Add child to parent (previous column)
                                {

                                    tNode = tNode.Nodes.Add(cell1Value);
                                }
                            }
                        }
                    }

migliori soluzioni sono sempre ben accette..
 
Ultima modifica da un moderatore:
Salve a tutti
il codice postato in precedenza se in un primo momento andava bene, in seguito mi sono accorto che sul nodo non tutti i valori unici della colonna vengono visualizzati, posto un immagine cosi da rendere più chiaro il mio problema:

Senza nome.webp

Riassumento in breve, non riesco a risolvere un ciclo sulla tabella che realizza la struttura dei nodi come da immagine a sx.
l'immagine non e altro che una tabella pivot fatta in excel. Sto realizzando una applicazione che mi genera una treeview come da immagine sopra.
Grazie
 
Ah, ora è chiaro cosa vuoi cercare di fare, vuoi stampare tutti i valori unici per tre campi della tabella.
Ma scusa, questo non ha nulla a che vedere con l’istruzione SQL PIVOT, che cambia le righe di una tabella in colonne di un’altra tabella, usando aggregazione (questo è quello che accomuna il tuo quesito).
 
Esattamente, ma in una struttura treeview.


Cattura02.webp

Questo e cio che sto cercando di implementare, come vedi sotto il nodo "INSTRUMENT CABLE" sulla treeview a sx devo vedere anche gli altri valori presenti sulla colonna "Breackdown header code" sulla dx, quindi oltre all'item "ZMNC" sul nodo "INSTRUMENTAL CABLE" sulla treeview dovrei vedere "SA03" ed "SA01".
In basso l'immagine dello stesso di cui sopra ma fatto sulla pivot di excel:
02.webp
come vedi questo e quello che voglio ottenere sulla treeview.
C#:
for (int row = 0; row < dtCsv.Rows.Count - 1; row++)
{
    TreeNode tNode = new TreeNode();

    for (int col = 0; col < dtCsv.Columns.Count; col++)
    {
        string cell1Value = dtCsv.Rows[row][col].ToString();
        string cell2Value = dtCsv.Rows[row + 1][col].ToString();

        if (col == 0)
        {
            if (cell1Value.Equals(cell2Value)) continue;
            tNode = treeView1.Nodes.Add(cell1Value);
        }
        else
        {
            tNode = tNode.Nodes.Add(cell1Value);
        }

    }
questo e il ciclo che sto usando in questo momento ma non restituisce ciò che voglio.
 

Allegati

  • Cattura.webp
    Cattura.webp
    55.5 KB · Visualizzazioni: 14
Beh, prima di tutto il tuo codice (dopo essere sistemato) confronta solo due valori consecutivi di riga, per cui non funziona in caso le righe non siano ordinate. Per questo devi usare due cicli innestati, per vedere se il valore corrente sia uguale a uno in qualsiasi riga precedente. Il codice diventerà complicato molto facilmente, con possibilità di introdurre errore (come vedi facilmente nel tuo caso è sarà veramente lento. Specie nella creazione e bel popolamento del TreeView. Ecco perché si usano I database, sono fatti per quello, ottenere i dati più velocemente possibile, raggrupparli e ordinarli come desiderato.
Come regola aurea, mai popolare completamente un TreeView, come ti ho detto è estremamente lento. Aggiungi solo i children del nodo principale, poi aggiungi i nodi solo quando l’utente li espande. Inutile aggiungere elementi che non saranno mai visualizzati.
 
Beh, prima di tutto il tuo codice (dopo essere sistemato) confronta solo due valori consecutivi di riga, per cui non funziona in caso le righe non siano ordinate. Per questo devi usare due cicli innestati, per vedere se il valore corrente sia uguale a uno in qualsiasi riga precedente. Il codice diventerà complicato molto facilmente, con possibilità di introdurre errore (come vedi facilmente nel tuo caso è sarà veramente lento. Specie nella creazione e bel popolamento del TreeView. Ecco perché si usano I database, sono fatti per quello, ottenere i dati più velocemente possibile, raggrupparli e ordinarli come desiderato.
Come regola aurea, mai popolare completamente un TreeView, come ti ho detto è estremamente lento. Aggiungi solo i children del nodo principale, poi aggiungi i nodi solo quando l’utente li espande. Inutile aggiungere elementi che non saranno mai visualizzati.
Hai perfettamente ragione, il caricamento della treeview in questo modo risulterebbe molto lento. Avevo pensato infatti, di creare una listbox con il caricamento delle colonne e tramite quelle selezionare al massimo le tre colonne per la realizzazione dei nodi.
Ormai è diventato un'ossessione sono giorni che tento di impostare un ciclo che mi restituisce il discorso di cui sopra, se riusciresti a postarmi magari qualche esempio te ne sarei grato..
Grazie
 
Io uso il GROUP BY statement, di cui puoi trovare un tutorial qui che e' ben fatto

E' in inglese, ma come saprai trovare qualcosa in italiano (che sia poi decente) non e' facile.

Con il primo GROUP BY puoi popolare i primi children dell'albero (magari li ordini in ordine alfabetico, o come preferisci)

Appena ricevi un evento dal nodo, effettua un altro GROUP BY aggiungendo il valore del nodo nella causa SELECT, e cosi' via.
 
provero con le istruzioni sql, daro un'occhiata al link che hai postato,, grazie per i consigli, postero il listato se riuscirò nell'intento. Cmq mi rimane sempre in sospeso quel ciclo for o che altro che non sono riuscito a trovare. ;.)
 
Ho trovato una soluzione per riportare un datatable in una struttura treenode tramite i seguenti passaggi:

C#:
private void BuildTreeView(DataTable dt)
        {
            TreeNode rootNode = new TreeNode("Root");
            foreach (DataRow row in dt.Rows)
            {
                string[] values = new string[dt.Columns.Count];
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    values[i] = row[i].ToString();
                }
                TreeNode node = rootNode;
                for (int i = 0; i < values.Length; i++)
                {
                    TreeNode childNode = FindChildNode(node, values[i]);
                    if (childNode == null)
                    {
                        childNode = new TreeNode(values[i]);
                        node.Nodes.Add(childNode);
                    }
                    node = childNode;
                }
            }
            treeView1.Nodes.Add(rootNode);
        }
        private TreeNode FindChildNode(TreeNode parentNode, string text)
        {
            foreach (TreeNode node in parentNode.Nodes)
            {
                if (node.Text == text)
                {
                    return node;
                }
            }
            return null;
        }

Saluti
 
  • Mi piace
Reazioni: BAT
Stato
Discussione chiusa ad ulteriori risposte.
Pubblicità
Pubblicità
Indietro
Top