Click here to Skip to main content
Click here to Skip to main content

TreeView with XML

, 19 Jun 2007
Rate this:
Please Sign up or sign in to vote.
Saving anbd loading a TreeView control to and from an XML file.

Introduction

The purpose of this article is to demonstrate the saving and loading of System.Windows.Forms.TreeView control from an XML file. XmlTextReader and XmlTextWriter of the System.Xml namespace are used for reading and generating XML files, respectively. It also demonstrates a simple XML file viewer using a TreeView control.

Background

The real functionality is enclosed in a class called TreeViewSerializer. It has two main responsibilities:

  1. Saving the TreeView to a specified XML file.
  2. 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:

<?xml version="1.0" encoding="us-ascii" ?> 
<TreeView>
   <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>
   <node text="Europe" imageindex="1">
      <node text="Germany" imageindex="6" /> 
      </node>
   <node text="America" imageindex="2" /> 
   <node text="Africa" imageindex="3" /> 
</TreeView>

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:

  1. Text
  2. ImageIndex
  3. Tag

I have serialized the above three attributes of the System.Windows.Forms.TreeNode object, it can be easily extended to include other attributes.

XmlNodeTag, XmlNodeTextAtt, XmlNodeTagAtt, and XmlNodeImageIndexAtt are the constants defined in the TreeViewSerializer class:

// Xml tag for node, e.g. 'node' in case of <node></node>
private const string XmlNodeTag = "node";

// Xml attributes for node e.g. <node text="Asia" tag="" 
// imageindex="1"></node>
private const string XmlNodeTextAtt = "text";
private const string XmlNodeTagAtt = "tag";
private const string XmlNodeImageIndexAtt = "imageindex";

Using the code

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 the DeserializeTreeView method:

public void DeserializeTreeView(TreeView treeView, string fileName)
{
   XmlTextReader reader = null;
   try
   {
        // disabling re-drawing of treeview till all nodes are added
        treeView.BeginUpdate();    
        reader = new XmlTextReader(fileName);
        TreeNode parentNode = null;
        while (reader.Read())
        {
             if (reader.NodeType == XmlNodeType.Element)
             {      
                  if (reader.Name == XmlNodeTag)
                  {
                       TreeNode newNode = new TreeNode();
                       bool isEmptyElement = reader.IsEmptyElement;
                
                       // loading node attributes
                       int attributeCount = reader.AttributeCount;
                       if (attributeCount > 0)
                       {
                          for (int i = 0; i < attributeCount; i++)
                          {
                              reader.MoveToAttribute(i);
                              SetAttributeValue(newNode, 
                                           reader.Name, reader.Value);
                          }        
                       }
                       // add new node to Parent Node or TreeView
                       if(parentNode != null)
                          parentNode.Nodes.Add(newNode);
                       else
                          treeView.Nodes.Add(newNode);
                
                       // making current node 'ParentNode' if its not empty
                       if (!isEmptyElement)
                       {
                          parentNode = newNode;
                       }
                  }                          
             }
             // moving up to in TreeView if end tag is encountered
             else if (reader.NodeType == XmlNodeType.EndElement)
             {
                  if (reader.Name == XmlNodeTag)
                  {
                           parentNode = parentNode.Parent;
                  }
             }
             else if (reader.NodeType == XmlNodeType.XmlDeclaration)
             { 
                  //Ignore Xml Declaration                    
             }
             else if (reader.NodeType == XmlNodeType.None)
             {
                  return;
             }
             else if (reader.NodeType == XmlNodeType.Text)
             {
                  parentNode.Nodes.Add(reader.Value);
             }
    
        }
   }
   finally
   {
        // enabling redrawing of treeview after all nodes are added
        treeView.EndUpdate();
        reader.Close(); 
   }
}

As XmlTextReader parses through the XML document, appropriate actions are taken depending on the NodeType. If the NodeType is 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 Text, Tag, and ImageIndex properties of a TreeNode, the SetAttributeValue method is called. It has the following implementation:

/// <summary>
/// Used by Deserialize method for setting properties of 
/// TreeNode from xml node attributes
/// </summary>
private void SetAttributeValue(TreeNode node, 
                 string propertyName, string value)
{
   if (propertyName == XmlNodeTextAtt)
   {                
        node.Text = value;
   }
   else if (propertyName == XmlNodeImageIndexAtt) 
   {
        node.ImageIndex = int.Parse(value);
   }
   else if (propertyName == XmlNodeTagAtt)
   {
        node.Tag = value;
   }  
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Mohammad Rizwan
Software Developer (Senior) Axact Pvt Ltd
Pakistan Pakistan
Sr Software Engineer
Axact Pvt Ltd
Karachi Pakistan

Comments and Discussions

 
QuestionArticle Title? PinmemberPaul A. Howes20-Jun-07 5:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140709.1 | Last Updated 19 Jun 2007
Article Copyright 2007 by Mohammad Rizwan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid