For our latest software venture, we needed to create a tree view listing of all the countries that we were going to support. Naturally, we created an XML input file that was formed like this:
1: <?xml version="1.0" encoding="utf-8" ?>
2: <Countries>
3: <Country Name="Argentina" value="http://buenosaires.en.craigslist.org">
4: </Country>
5: <Country Name="Australia" value="http://sydney.craigslist.com.au">
6: <Region Name="Adelaide" value="http://adelaide.craigslist.com.au" />
7: <Region Name="Brisbane" value="http://brisbane.craigslist.com.au" />
8: <Region Name="Cairns" value="http://cairns.craigslist.com.au" />
9: <Region Name="Canberra" value="http://canberra.craigslist.com.au" />
10: <Region Name="Darwin" value="http://darwin.craigslist.com.au" />
11: <Region Name="Gold Coast" value="http://goldcoast.craigslist.com.au" />
12: <Region Name="Melbourne" value="http://melbourne.craigslist.com.au" />
13: <Region Name="Newcastle" value="http://ntl.craigslist.com.au" />
14: <Region Name="Perth" value="http://perth.craigslist.com.au" />
15: <Region Name="Sydney" value="http://sydney.craigslist.com.au" />
16: <Region Name="Tasmania" value="http://hobart.craigslist.com.au" />
17: <Region Name="Wollongong" value="http://wollongong.craigslist.com.au" />
18: </Country>
19: <Country Name="Austria" value="http://vienna.en.craigslist.at">
20: </Country>
21: ... and so on...
The problem was that XML requires a root element (in this case, Countries). This meant that just blindly loading the XML left us with a single root node (Countries) with all the individual country information (Country) listed below that. We wanted to start our TreeView with the Country listings as root elements.
The solution was to create a reader function that would skip the root element found in traditional reader samples, like the example on Microsoft’s MSDN site. We created a function here that does just that.
1: private void OnFormLoad(object sender, EventArgs e)
2: {
3: try
4: {
5: XmlDocument dom = new XmlDocument();
6: dom.Load("CountryList.xml");
7: treeView1.Nodes.Clear();
8: AddTreeViewChildNodes(treeView1.Nodes, dom.DocumentElement);
9: treeView1.Refresh();
10: treeView1.CollapseAll();
11: }
12: catch (XmlException xmlEx)
13: {
14: MessageBox.Show(xmlEx.Message);
15: }
16: catch (Exception ex)
17: {
18: MessageBox.Show(ex.Message);
19: }
20: }
21:
22: private void AddTreeViewChildNodes(TreeNodeCollection parent_nodes, XmlNode xml_node)
23: {
24: foreach (XmlNode child_node in xml_node.ChildNodes)
25: {
26: // Make the new TreeView node.
27: TreeNode new_node = parent_nodes.Add(child_node.Attributes["Name"].Value);
28: // Recursively make this node's descendants.
29: AddTreeViewChildNodes(new_node.Nodes, child_node);
30: // If this is a leaf node, make sure it's visible.
31: if (new_node.Nodes.Count == 0) new_node.EnsureVisible();
32: }
33: }
The code is deceptively simple… It’s only 3 lines of recursive C#. You can always change the text that is displayed by manipulating the child_node.Attributes["Name"].Value line. It’s important to call treeView1.Refresh() when the function is complete to ensure all of the boxes and nodes are fully drawn.
What we’re left with is a nice TreeView control that has each country listed as a root element, despite what the XML says.
BTW: If your wondering how we did the 3 state checkbox, that information will be provided in a later post.
070e0bd2-a93a-4439-a023-77ee682170fa|1|5.0