Browse DevX
Sign up for e-mail newsletters from DevX


Making the Most of the VB TreeView Control : Page 4

Add run-time editing, drag-and-drop features and persistence to the TreeView control.

Persisting the Nodes Collection
The TreeView control doesn't provide a Save (neither a Load) method, so we'll have to implement our own routines for persisting the control's nodes. The simplest way to save a TreeView control's Nodes collection is in XML format, because XML gives you intrinsic support for hierarchical structures. The sample code uses the MSXML component to create an XML document that contains the data and structure of the TreeView control's nodes. VB6 doesn't install MSXML by by default, but you can download it from MSDN and install it on your computer. The sample code uses MSXML version 3 (sp2), but you can use either version 3 or 4.

To use the MSXML component in your code, add a reference to the class to your project: open the Project menu, select References and on the References dialog box check the Microsoft XML v3.0 (or 4.0) component. This class provides all the methods you need to either create or read an XML document and process its nodes.

The Save Nodes button on the main form creates a "flat" XML document: each node is saved as a separate element and the node's properties (the node's caption, key and the parent node's key) are saved as attributes of the element. In other words, this version stores the hierarchical structure as relationships inherent in the ParentKey node attributes. The code creates a <NODE> XML element for each Node object in the TreeView's Nodes collection. Each <NODE> element has four attributes: Caption, Key, Tag and ParentKey. The resulting document looks like this:

The ParentKey attribute is the ID of the parent node, so you can reconstruct the node hierarchy later. Listing 3 shows the code behind the Save button. The code creates the root element <NODES> and then iterates through the control's nodes with a For...Next loop. Each iteration creates a new <NODE> element, retrieves the values of its attributes from the current node's properties and then adds the element under the root element.

A Better XML Structure

The XML document generated by the Save Nodes button is a valid XML document and it contains all the information we need to reconstruct the original Nodes collection on the control. However, it doesn't reflect the hierarchical structure of the collection. Take a look at the following XML document, which nests the nodes under their parent nodes. Here's an excerpt of of the document:

     <NODE Caption="Asia" Key="K5334241" 
        Tag="" ParentKey="">
       <NODE Caption="Japan" Key="K4687002" 
         Tag="" ParentKey="K5334241">
          <NODE Caption="Tokyo" Key="K6478212" 
            Tag="" ParentKey="K4687002" /> 
     <NODE Caption="Europe" Key="K7055476" 
        Tag="" ParentKey="">
        <NODE Caption="France" Key="K7607236" 
           Tag="" ParentKey="K7055476">
          <NODE Caption="Paris" Key="K453528" 
             Tag="" ParentKey="K7607236" /> 
         <NODE Caption="Lyon" Key="K4140327" 
             Tag="" ParentKey="K7607236" /> 
Figure 2. Viewing the persisted XML file in Internet Explorer after saving the Treeview with the nodes shown on in Figure 1.
Notice how this representation nests country nodes within continent nodes and city nodes within country nodes, clearly reflecting the structure of the control's Nodes collection. While this representation doesn't provide any programmatic advantages over the "flat" version, it's much easier for humans to read. . As you will shortly see, the routine that reads the XML nodes and populates the TreeView control is the same, no matter how you choose to structure the XML file.

The code behind the Save Nodes (Nested) button loops through the root nodes of the TreeView control adding each node to the XML document's root element and then calls the AddChildNodes subroutine to add the current node's child nodes. Listing 4 shows this code.

The AddChildNodes() subroutine does all the work and is surprisingly simple. Like most recursive routines, the AddChildNodes() subroutine is both short and efficient. It creates a <NODE> element for the current node and writes it to the XML document. It doesn't close the <NODE> element immediately; instead, it loops through any child nodes of the current node, calling itself recursively for each child node, and closes the initial <Node> element only after storing all the child nodes. Listing 5 shows the AddChildNodes() subroutine.

Thanks for your registration, follow us on our social networks to keep up-to-date