TreeView a cascata ... modalità di gestione

martedì 25 aprile 2006 - 17.18

MordadellaGay Profilo | Junior Member

Ciao, ho trovato diversi esempio on line ma non ho ben capito come gestire una struttura ad N livelli in una tree view.

Io ho una tabella con una struttura del tipo

padre - figlio - valore
1 - 2 - XX
1 - 3 - ZZ
1 - 4 - KK
1 - 5 - HH
6 - 1 - YY
...

quindi il padre viene ripetuto X volte in questa tabella e inoltre potrei utilizzare un padre per fare da figlio ad un nuovo nodo/elemento (ecco perchè parlo di struttura ad N livelli)

Dubbio: ho capito come popolare il primo livello (la radice):

carico la tabella sopra indicata nel dataset e per ogni elemento creo il primo livello nel mio treeview... fin qui tutto ok

a questo punto ho un dubbio:
posso lavorare SOLO con la tabella di dettaglio (quello che ho indicato sopra), senza "collegarmi" ad una tabella che contiene l'elenco dei "padri"???
Cchiedo questo perchè attualmente il risultato del mio albero è

partendo da una tabella del tipo:

padre - figlio - valore
1 - 2 - XX
1 - 3 - ZZ
1 - 4 - KK
1 - 5 - HH
6 - 1 - YY

ottengo una treeview ad un livello con i seguenti nodi radice:
1
1
1
1
6

io invece dovrei vedere una sola volta, nel nodo radice, l'elemento "1"; questo è dovuto al fatto che io copio nel dataset tutti gli elemeti della mia tabella sopra indicata, ma (e veniamo al mio dubbio), devo caricare nel dataset anche una tabella con l'elenco dei padri??? in caso affermativo:
- come identifico i padri? considerando che devo gestire un albero ad N livelli? (nel mio caso 1 è sia padre che figlio)
- come creo in nodi successivi?? sempre collegandomi al discorso degli N livelli

Spero di essere stato chiaro!

Grazie a tutti per l'aiuto e per la pazienza nel leggere il post!!

Cteniza Profilo | Guru

Ogni oggetto treeview ha una collection di TreeNode "Nodes", ciascun TreeNode a sua volta può avere una collection di altri TreeNode "Nodes".
Quindi non devi far altro che appendere i tuoi nodi in successione alla collection nodes "giusta".
Di solito si usa la ricorsività per leggere in maniera scalare (padre / figli) i dati e appendere al padre i nodi figli che poi diventano a loro volta i nodi a cui vengono appesi i figli e così via fino al completo "svolgimento" dei dati.

MordadellaGay Profilo | Junior Member

Ci sto provando... ma è un po' un casino

Grazie per la risposta

MordadellaGay Profilo | Junior Member

Per il primo nodo OK

itero il datatable e faccio un node.Add

ma per i successivi??

come faccio a gestire una situazione di questo tipo

Per ogni nodo del livello +1 verifica i figli nel dataset
Per ogni nodo del livello +2 verifica i figli nel dataset

intendo: come itero i vari nodi per aggiungere i figli??

Grazie

Cteniza Profilo | Guru

Ho realizzato un esempio di gestione treeview che ho messo nel mio blog.
http://community.visual-basic.it/LucianoB/archive/2006/04/25/17107.aspx

MordadellaGay Profilo | Junior Member

Ciao, sto cercando di seguire il tuo esempio... ma non capisco dove sbaglio;

la premessa è che io dovrei gestire N livelli e non 5 come nel tuo caso.

Ho due tabelle:
Articoli: dove ho tutti gli articoli che verranno dettagliati in distinta base
ID - Codice - Descrizione
DistintaBase: elenco dei componenti di ogni articolo
ID (contatore che non serve a nulla) - IDPadre - ID_ArticoliComponenti

quindi ogni articolo, nel caso in cui sia un articolo prodotto, avrà la relativa esplosione nella tabella DistintaBase

Con il codice che posto sotto ottengo una lista di codici senza alcun nodo...

Grazie per l'aiuto

private void frmDistinteBase_Load(object sender, System.EventArgs e)
{
string _nomeTabellaPF = "ArticoliProdotti";
tb_prod_DistinteBase _distinteBase = new tb_prod_DistinteBase();
// DataSet prodotti finiti
DataSet dsArticoliProdotti = new DataSet();
// Vengono caricati nel DataTable gli articoli prodotti
dsArticoliProdotti = (lmc.FillDataSet(_distinteBase.SqlSelectPFAll(), _nomeTabellaPF));

// Carico nella radice principale gli articoli prodotti
foreach (DataRow row in dsArticoliProdotti.Tables[0].Rows)
{
TreeNode node = new TreeNode();
// Testo della Label
node.Text = row["ID"].ToString();
// Campo visualizzato del DB
node.Name = row["ID"].ToString();
tvwDistinteBase.Nodes.Add(node);
BuildTreeView(Convert.ToInt32(row["ID"]), node);
}
}





public void BuildTreeView(int IDPadre, TreeNode NodoPadre)
{
string _nomeTabellaComponenti = "DistinteBase";
tb_prod_DistinteBase _distinteBase = new tb_prod_DistinteBase();
// DataSet prodotti finiti
DataSet dsDistinteBase = new DataSet();
// Vengono caricati nel DataTable gli elementi delle distinte base
dsDistinteBase = (lmc.FillDataSet(_distinteBase.SqlSelectComponentiAll(), _nomeTabellaComponenti));

// Carico nella radice principale gli articoli prodotti
foreach (DataRow row in dsDistinteBase.Tables[0].Select("ID_Padre = " + IDPadre))
{
TreeNode node = new TreeNode();
// Testo della Label
node.Text = row["ID_ArticoliComponenti"].ToString();
// Campo visualizzato del DB
node.Name = row["ID_ArticoliComponenti"].ToString();
BuildTreeView(Convert.ToInt32(row["ID_ArticoliComponenti"]), node);
tvwDistinteBase.Nodes.Add(node);
}
}

Cteniza Profilo | Guru

Io ho messo un limite ai numeri di livelli interni solo per la generazione dei dati e non per la gestione della treeview che può avere un numero anche maggiore di livelli interni.
Era funzionale solo al mio esempio.

MordadellaGay Profilo | Junior Member

Aggià è vero!! Hai ragione

Ma dove sbaglio nel mio codice??

Grazie

Cteniza Profilo | Guru

Verifica il tuo codice
// Campo visualizzato del DB
node.Name = row["ID_ArticoliComponenti"].ToString();
BuildTreeView(Convert.ToInt32(row["ID_ArticoliComponenti"]), node);
tvwDistinteBase.Nodes.Add(node); << questa riga è errata
dovrebbe essere:
NodoPadre.Nodes.Add(node);

eikichi Profilo | Newbie

Scusate se mi intrometto...

mi pare che l'errore stia nell'ultima riga della funzione
BuildTreeView(int IDPadre, TreeNode NodoPadre)
(
tvwDistinteBase.Nodes.Add(node);
)

il nuovo nodo deve essere aggiunto a NodoPadre, non alla TreeView

MordadellaGay Profilo | Junior Member

Eggià!!

Avete proprio ragione. Il problema era proprio quello!!!

Vi chiedo un ultima informazione:

che differenza c'è tra Nodo.Text e Nodo.Name??
quale dei due devo utilizzare per visualizzare la descrizione del codice??

MordadellaGay Profilo | Junior Member

Eggià!!

Avete proprio ragione. Il problema era proprio quello!!!

Vi chiedo un ultima informazione:

che differenza c'è tra Nodo.Text e Nodo.Name??
quale dei due devo utilizzare per visualizzare la descrizione del codice??

Grazie infinite per l'aiuto e per la velocissima risposta!

eikichi Profilo | Newbie

Nodo.Name è il nome dell'oggetto TreeNode.

Nodo.Text ti permette di impostare l'etichetta del nodo, quindi devi usare questa proprietà.

MordadellaGay Profilo | Junior Member

Quindi Nodo.Name dovrà essere comune a tutti i nodi (padri e figli)??

Grazie ancora!

Cteniza Profilo | Guru

Nel mio esempio come puoi vedere non ho fatto uso della proprietà "Name".
E' un elemento "chiave" per il nodo all'interno della treenode collection.
Non l'ho mai utilizzato ma se scorri i nodi con:
foreach TreeNode nodo in myTreeView.Nodes
{
}
probabilmente li ottieni ordinati per nome.

eikichi Profilo | Newbie

>Quindi Nodo.Name dovrà essere comune a tutti i nodi (padri e
>figli)??
>
>Grazie ancora!

No, forse mi sono espresso male.

La proprietà "Name" rappresenta il nome di ciscun nodo.

In realtà Name viene ereditato dalla classe Control e rappresenta quindi il nome di un controllo che solitamente viene posto uguale al nome della variabile oggetto utilizzata per quel controllo.

MordadellaGay Profilo | Junior Member

Dato che siamo in tema in questo thread, vorrei chiedere un ulteriori aiuto su come struttura una procedura ricorsiva ....

partendo da una tabella del tipo:

ID_Padre - ID_Figlio - Valore
11 - 22 - 1
11 - 33 - 2
11 - 44 - 3
33 - 55 - 4
33 - 66 - 5
55 - 77 - 6
55 - 88 - 7

Quindi come potete questa "distinta base" ha una struttura ad albero del tipo

11
- 22
- 33
-- 55
---77
---88
-- 66
- 44

Io vorrei, dato un nodo in qualunque posizione (quindi dato un ID_Padre) arrivare a somma il valore di tutte le sue foglie (non dei nodi intermedi), quindi considerando 11, vorrei sommare i valori di

22 + 66 + 77 + 88 + 44

In quanto

77 + 88 = 55 quindi ho (virtualmente) 55 e quindi ho già tutti i componenti di 33 (che quindi non devo calcolare) dato che è composto da 55 + 66

Ecco perchè, se nelle mie prove non ho fatto errori, per sapere il valore di ogni nodo, basta inserire il valore di tutte le foglie

Grazie per l'aiuto
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5