TreeView anhand einer XML generieren
-
Hallo,
ich stehe vor einem Problem. Ich würde gerne eine TreeView anhand einer XML zusammen bauen. Ich bekomme es einfach nicht gebacken. Ich dachte wohl es ist einfacher als es aussieht.
Vielleicht ist mein Kompletter ansatz mißt.
Hier meine XML:
<?xml version="1.0" encoding="utf-8" ?>
<tree>
<node name="Baum">
<node name="Ast 1">
<node name="Blatt 1" id="h1"/>
<node name="Blatt 2" id="h2"/>
</node>
<node name="Ast 2">
<node name="Blatt 1" id="b1"/>
<node name="Blatt 2" id="b2"/>
</node>
</node>
<node name="2. Baum zum test"/>
</tree>Ich hoffe ich hab das einigermaßen richtig gemacht.
Hier mein Codeansatz
// DOM Objekt erzeugen und XML-Datei laden XmlDocument xmlTreeDom = new XmlDocument(); xmlTreeDom.Load("Data/treedata.xml"); // Verzeichnisbaum initialisieren treeView1.Nodes.Clear(); // Verzeichnisstruktur entfernen XmlNodeList nodeList = xmlTreeDom.DocumentElement.ChildNodes; foreach (XmlNode node in nodeList) { treeView1.Nodes.Add(new TreeNode(node.Attributes["name"].Value)); Console.WriteLine("Tree: " + node.Attributes["name"].Value); if (node.Attributes["name"].HasChildNodes) { Console.WriteLine("Nodes->"); TreeNode tNode = new TreeNode(); tNode = treeView1.Nodes["name"]; AddNodes(xmlTreeDom, tNode); } }
Die Wurzelbäume schreibt er ja in die TreeView. Nun hat der 1. Baum ja unterelemente und wie geht es dann weiter? Ich wollte irgendwie jetzt den aktuellen node haben aber mit "treeView1.Nodes["name"];" geht das nicht.
Laut der Testconsolenausgabe hätte der 2. Baum auch unterelemente. Ich denke mal das "if (node.Attributes["name"].HasChildNodes)" falsch ist und sich auf alle bezieht.
Kann mir da jemand helfen?
Danke euch
-
Du musst dich da rekursiv durchhangeln.
Die untenstehende Version ist so ein wenig pseudocode, auch ungetestet, aber so in dem Rahmen solltest du vorgehen.private void ReadXmlRecursive(XmlNode node) { foreach(XmlNode n in node.Children) { //mahc irgendwas if(n.HasChildes) ReadXmlRecursive(n); } }
-
Bin glaube ich auf dem besten Weg dazu.
Mein erster Fehler war schonmal hier:
tNode = treeView1.Nodes["name"];Dies hab ich schon mal zu dem geändert:
tNode = treeView1.Nodes[0];War so auf XML eingestellt und hab ganz vergessen das ich ja ein TreeView jetzt bearbeite.
Zumindest werden jetzt die Unterknoten gemacht.
Dann muss ich wohl wieder den aktuellen Knoten an meine Funktion geben und der dann dort weitere Knoten erstellt.
-
So jetzt bleibe ich wieder ein wenig hängen
Aber sieht bis jetzt eigentlich nicht schlecht aus.
Hier meine Funktion um die Unterelemente zu erzeugen:
private void AddNodes(XmlNode inXmlNode, TreeNode inTreeNode) { //inTreeNode.Nodes.Add(new TreeNode("test")); XmlNodeList nodeList; if (inXmlNode.Attributes["name"].HasChildNodes) { nodeList = inXmlNode.ChildNodes; int nodecount = 0; foreach (XmlNode node in nodeList) { inTreeNode.Nodes.Add(new TreeNode(node.Attributes["name"].Value)); if (node.Attributes["name"].HasChildNodes) { TreeNode tNode = new TreeNode(); tNode = treeView1.Nodes[0].Nodes[nodecount++]; AddNodes(node, tNode); } } //inTreeNode.Nodes.Add(new TreeNode(inXmlNode.Attributes["name"].FirstChild["name"].Value)); } }
So sieht der Baum danach aus:
Baum
|- Ast 1
|- Blatt 1
|- Blatt 2Problem ist momentan das hier
tNode = treeView1.Nodes[0].Nodes[nodecount++];
Kommt dann die exception index außerhalb des Bereichs.
Der Scheiter dann wenn "treeView1.Nodes[0].Nodes[1];" ist. Sollte doch dann Ast 2 sein. Hmmm. Vielleicht Sieht ja jemand den Fehler.?
Über die Index die ganzen Nodes anzusteuern ist eh nicht elegant. Das muss sich noch ändern. Ich darf nicht am treeView1 auß gehen.
-
Perfekt ich habs
Fehler war hier drinnen:
tNode = treeView1.Nodes[0].Nodes[nodecount++];
Mußte ich ändern in:
tNode = inTreeNode.Nodes[nodecount++];
Perfekt.
-
Du könntest auch Linq To Xml benutzen. Da brauchst du dann auch keine Rekursion mehr.
-
@Dragon:
Ich hab dir mal eine noch kürzere Variante gemacht.namespace TreeView { public partial class Form1 : Form { private XmlDocument _doc; public Form1() { InitializeComponent(); _doc = new XmlDocument(); _doc.Load("test.xml"); this.AddNodes(_doc.FirstChild.NextSibling, treeView1.Nodes.Add("tree")); } private void AddNodes(XmlNode inXmlNode, TreeNode inTreeNode) { foreach (XmlNode n in inXmlNode.ChildNodes) { TreeNode node = inTreeNode.Nodes.Add(n.Attributes["name"].Value); if (n.HasChildNodes) AddNodes(n, node); } } } }