The purpose of this article is to demonstrate the saving and loading of
System.Windows.Forms.TreeView control from an XML file.
System.Xml namespace are used for reading and generating XML files respectively. It also demonstrates a simple XML file viewer using a
The real functionality is enclosed in a class called
TreeViewSerializer. It has two main responsibilities:
- Saving the
TreeView to a specified XML file.
- Loading the
TreeView from any specified XML file.
The structure of an XML file used for serializing a
TreeView is quite simple. Following is a sample XML file included with the attached project:
<node text="Asia" imageindex="0">
<node text="China" imageindex="-1" tag="Largest Population">
<node text="Beijing" imageindex="-1" /></node>
<node text="Pakistan" imageindex="4" />
<node text="India" imageindex="5" />
<node text="Srilanka" imageindex="6" />
<node text="Europe" imageindex="1">
<node text="Germany" imageindex="6" />
<node text="America" imageindex="2" />
<node text="Africa" imageindex="3" />
After the XML declaration, all the nodes are enclosed in a
TreeView tag. The
TreeView tag may contain multiple
node tags. The
node tag can also contain other
node tags. Each
node tag can have three attributes:
I have serialized the above three attributes of
System.Windows.Forms.TreeNode object, it can be easily extended to include other attributes.
XmlNodeImageIndexAtt are the constants defined in
private const string XmlNodeTag = "node";
private const string XmlNodeTextAtt = "text";
private const string XmlNodeTagAtt = "tag";
private const string XmlNodeImageIndexAtt = "imageindex";
Loading TreeView from XML – Deserialization
The deserialization is performed by the
DeserializeTreeView method which uses
XmlTextReader to parse through the XML document and fill the
TreeView object. Following is the definition of
public void DeserializeTreeView(TreeView treeView, string fileName)
XmlTextReader reader = null;
reader = new XmlTextReader(fileName);
TreeNode parentNode = null;
if (reader.NodeType == XmlNodeType.Element)
if (reader.Name == XmlNodeTag)
TreeNode newNode = new TreeNode();
bool isEmptyElement = reader.IsEmptyElement;
int attributeCount = reader.AttributeCount;
if (attributeCount > 0)
for (int i = 0; i < attributeCount; i++)
if(parentNode != null)
parentNode = newNode;
else if (reader.NodeType == XmlNodeType.EndElement)
if (reader.Name == XmlNodeTag)
parentNode = parentNode.Parent;
else if (reader.NodeType == XmlNodeType.XmlDeclaration)
else if (reader.NodeType == XmlNodeType.None)
else if (reader.NodeType == XmlNodeType.Text)
XmlTextReader parses through the XML document, appropriate actions are taken depending on the
NodeType. If the
Element, a new
TreeNode is created and its properties are set using the XML node attributes. The
ParentNode is set to the new
TreeNode in case of non-empty elements so that its child nodes are deserialized. If an
EndElement is encountered, the
ParentNode is set to the parent of the current parent node indicating that all the child nodes of the current node are deserialized.
For setting the
ImageIndex properties of a
SetAttributeValue method is called. It has the following implementation:
Saving TreeView – Serialization
SerializeTreeView saves the
System.Windows.Forms.TreeView to the specified file. Following is the method definition:
public void SerializeTreeView(TreeView treeView, string fileName)
XmlTextWriter textWriter = new XmlTextWriter(fileName,
The above code I guess is pretty much self explanatory. The
- Instantiates the
XmlTextWriter, passing it the provided filename.
- XML declaration (<?xml version="1.0" encoding="us-ascii" ?>) is written to the stream.
TreeView tag is written to the stream.
SaveNodes method is called. The
TreeNode collection in a
TreeView is passed to it, it saves all the nodes in a
TreeView to the stream calling itself recursively. Its definition is produced below.
- The end tag of
TreeView is written.
- And finally the stream is closed.
Following is the definition of
private void SaveNodes(TreeNodeCollection nodesCollection,
for(int i = 0; i < nodesCollection.Count; i++)
TreeNode node = nodesCollection[i];
if(node.Tag != null)
if (node.Nodes.Count > 0)
SaveNodes method loops through the
TreeNode collection, and writes the
node tag and its attributes. If a
node has child nodes then the method is called recursively. After the method returns, having written the child nodes to the stream, the node end tag is written.
XML File Viewer
There is another method in the
TreeViewSerializer class called
LoadXmlFileInTreeView. This can be used to view any XML document in the
TreeView. The following screen shot displays our sample XML file loaded into the
The code for loading an XML file is pretty much similar to the
SerializeTreeView method. I am not including the code here for the sake of brevity. You can find it in the attached source code.
A demo application is provided with the article as the driver of
TreeViewSerializer functionality. It has three functions:
- Save: save/serialize the
TreeView to an XML file. A
SaveFileDialog appears for specifying the file.
- Load: load/deserialize the
TreeView from an XML file.
- View XML File: to view any XML file in the
The XML document can also be manipulated using the DOM based
XmlNode classes. They are useful if we require searching and editing of XML document. In our case,
XmlTextReader are more efficient as they operate in a forward only, non-cached manner.
The generated XML file is not formatted by inserting a new line and tabs. Use
textWriter.WriteRaw("\r\n"); at appropriate places in
SerializeTreeView for this purpose. Obviously, you may use IE to view the formatted XML file. :)