Laden...

Wie kann ich ein TreeView rekursiv füllen?

Erstellt von Bonaqua vor 3 Jahren Letzter Beitrag vor 3 Jahren 745 Views
B
Bonaqua Themenstarter:in
35 Beiträge seit 2011
vor 3 Jahren
Wie kann ich ein TreeView rekursiv füllen?

Hallo,

ich stehe gerade echt auf dem Schlauch, wie ich mein TreeView (rekursiv?) befüllt bekomme.

Die Datenstruktur in meiner DB-Tabelle sieht so aus:
Spalten
parent_nr
parent_version
child_nr
child_version
count

Dies sieht dann etwa so aus:
"7500";"a";"1200";"0";1
"7500";"a";"2200";"0";2
"7500";"a";"2250";"0";1
"1200";"0";"1100";"0";1
"1200";"0";"1300";"0";1
"1300";"0";"1000";"0";1

Nun hätte ich gerne, dass es im TreeView korrekt aufgelistet wird. Zum Anzeigen wird nur ein "main"-Parent benötigt, da der Nutzer dies zuvor auswählen soll. Wie im oben Beispiel wäre das dann die 7500.

Somit sollte es wie folgt aussehen

Leider erhalte ich mit meinem Versuch immer eine StackOverflowException

TreeNode parentNode = new TreeNode("7500");
nummer = "7500";

public voidTreeViewErzeugen(string nummer, TreeNode parentNode)
        {
            parentNode.Name = nummer;
            try
            {
                string child;

                foreach (DataRow row in dt.Rows)
                {
                    child = row["child_nr"].ToString();

                    TreeNode myNode = new TreeNode(child);
                    myNode.Name = row["child_nr"].ToString();
                    parentNode.Nodes.Add(myNode);

                    PopulateTreeView(row["child_nr"].ToString(), myNode);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

Würde mich freuen, wenn mir jemand helfen könnte. Danke.

4.938 Beiträge seit 2008
vor 3 Jahren

Du iterierst ja auch jeweils über alle Einträge der Tabelle (dt.Rows).
Du darfst nur die Children eintragen, die direkte Subchildren des aktuell übergebenen Knotens sind.

PS: Du kannst die Rekursion mit PopulateTreeView(child, myNode) aufrufen (anstatt Neuberechnung des ersten Parameters) - außerdem bei der Zuweisung zu myNode.Name ebenso.

B
Bonaqua Themenstarter:in
35 Beiträge seit 2011
vor 3 Jahren

Hallo Th69,

danke für deine Antwort.
In meiner DataTable filtere ich auf die "7500" (Auswahl des Nutzers). Dann sollte es doch passen, welche Einträge durchlaufen werden?

außerdem bei der Zuweisung zu myNode.Name ebenso.

Dein Teil verstehe ich leider nicht, was du damit meinst.

4.938 Beiträge seit 2008
vor 3 Jahren

Von der Filterung sehe ich aber nichts im Code (ansonsten debugge doch einfach deinen Code).

PS: Und ich meinte myNode.Name = child.
Edit: Und ich sehe gerade, daß diese Zeile ja überflüssig ist, da du den Parameter ja schon im Konstruktor übergibst.

B
Bonaqua Themenstarter:in
35 Beiträge seit 2011
vor 3 Jahren

Ich habe nun nochmals einiges geändert. Leider erhalte ich weiterhin eine StackOverflowException.
Leider komme ich nicht weiter.
Was mache ich falsch??

Hier meine Klasse:


public class p_ident
    {
        public string ident;
        public string ben1;
    }

    public class c_ident : p_ident
    {
        public string pos_nr;
        public string count;
    }


 void rek_CreateNode(TreeNodeCollection nodes, p_ident ident)
        {
            TreeNode new_node = new TreeNode();
            c_ident child_product = ident as c_ident;
            if (child_product != null)
            {
                new_node.Text = child_product.ident + " " + child_product.ben1;
            }
            else
            {
                new_node.Text = ident.ident + " " + ident.ben1;
            }
            nodes.Add(new_node);

            List<c_ident> child_products = DB.Childs_BaugruppenListe(ident.ident);

            foreach (c_ident c in child_products)
            {
                rek_CreateNode(new_node.Nodes, c);
            }
        }


        void AufrufTree(string parent)
        {
            treeViewBaugruppenliste.Nodes.Clear();
            
            List<p_ident> parent_products = DB.Top_Baugruppenliste(parent);

            foreach (p_ident p in parent_products)
            {
                rek_CreateNode(treeViewBaugruppenliste.Nodes, p);
            }
        }


B
Bonaqua Themenstarter:in
35 Beiträge seit 2011
vor 3 Jahren

Ich habe nun den Fehler gefunden, dieser lag an der DB-Abfrage.

Soweit so gut. Nun enthält mein TreeView eine weitere Ebene.
Wie muss ich nun meine Aufrufe weiter fortführen, um den Baum maximal zu vertiefen?

Muss ich dan Baum durchlaufen, dann jeweils due Subelemente als Parent übergeben und wieder die Schleife rekursiv durchlaufen?

5.658 Beiträge seit 2006
vor 3 Jahren

Wenn du eine StackOverflowException bekommst, dann läuft deine Rekursion in einer Endlosschleife, d.h., die Rekursion wird niemals beendet.

Leider ist dein Quellcode absolut unlesbar, das fängt schon bei der Namensgebung der Variablen und Klassen an. Und niemand weiß, was z.B. Childs_BaugruppenListe macht.

Verwende einfach den Debugger, um herauszufinden, was dein Code macht, und warum die Rekursion niemals beendet wird.

[Artikel] Debugger: Wie verwende ich den von Visual Studio?
[Artikel] C#: Richtlinien für die Namensvergabe

Weeks of programming can save you hours of planning

B
Bonaqua Themenstarter:in
35 Beiträge seit 2011
vor 3 Jahren

@MrSparkle
Das Problem, mit der StackOverflowException konnte ich lösen.

Mein Problem ist "nur" noch, wie ich eine weitere Vertiefung des TreeView erreiche?

5.658 Beiträge seit 2006
vor 3 Jahren

Genau dafür verwendest du doch die Rekursion. Die läuft so lange durch, bis es keine weiteren Unterebenen gibt.

Weeks of programming can save you hours of planning