15.9 TreeView Control

The TreeView control displays nodes hierarchically in a tree. Traditionally, nodes are objects that contain values and can refer to other nodes. A parent node contains child nodes, and the child nodes can be parents to other nodes. Two child nodes that have the same parent node are considered sibling nodes. A tree is a collection of nodes, usually organized in a hierarchical manner. The first parent node of a tree is the root node (a TreeView can have multiple roots). For example, the file system of a computer can be represented as a tree. The top-level directory (perhaps C:) would be the root, each subfolder of C: would be a child node and each child folder could have its own children. TreeView controls are useful for displaying hierarchical information, such as the file structure that we just mentioned. We cover nodes and trees in greater detail in Chapter 19, Custom Linked Data Structures. Figure. 15.24 displays a sample TreeView control on a Form.

Fig. 15.24 TreeView displaying a sample tree.

A parent node can be expanded or collapsed by clicking the plus box or minus box to its left. Nodes without children do not have these boxes.

The nodes in a TreeView are instances of class TreeNode. Each TreeNode has a Nodes collection (type TreeNodeCollection), which contains a list of other TreeNodes—known as its children. The Parent property returns a reference to the parent node (or null if the node is a root node). Figures 15.25 and 15.26 list the common properties of TreeViews and TreeNodes, common TreeNode methods and a common TreeView event.

Fig. 15.25 TreeView properties and an event.

TreeView properties and an event Description
Common Properties
CheckBoxes Indicates whether CheckBoxes appear next to nodes. A value of true displays CheckBoxes. The default value is false.
ImageList Specifies an ImageList object containing the node icons. An ImageList object is a collection that contains Image objects.
Nodes Returns the collection of TreeNodes in the control as a TreeNodeCollection. It contains methods Add (adds a TreeNode object), Clear (deletes the entire collection) and Remove (deletes a specific node). Removing a parent node deletes all of its children.
SelectedNode The selected node.
Common Event (Event arguments TreeViewEventArgs)
AfterSelect Generated after selected node changes. This is the default event when the control is double clicked in the designer.

Fig. 15.26 TreeNode properties and methods.

TreeNode properties and methods Description
Common Properties
Checked Indicates whether the TreeNode is checked (CheckBoxes property must be set to true in the parent TreeView).
FirstNode Specifies the first node in the Nodes collection (i.e., the first child in the tree).
FullPath Indicates the path of the node, starting at the root of the tree.
ImageIndex Specifies the index in the TreeView’s ImageList of the image shown when the node is deselected.
LastNode Specifies the last node in the Nodes collection (i.e., the last child in the tree).
NextNode Next sibling node.
Nodes Collection of TreeNodes contained in the current node (i.e., all the children of the current node). It contains methods Add (adds a TreeNode object), Clear (deletes the entire collection) and Remove (deletes a specific node). Removing a parent node deletes all of its children.
PrevNode Previous sibling node.
SelectedImageIndex Specifies the index in the TreeView’s ImageList of the image to use when the node is selected.
Text Specifies the TreeNode’s text.
Common Methods
Collapse Collapses a node.
Expand Expands a node.
ExpandAll Expands all the children of a node.
GetNodeCount Returns the number of child nodes.

To add nodes to the TreeView visually, click the ellipsis next to the Nodes property in the Properties window. This opens the TreeNode Editor (Fig. 15.27), which displays an empty tree representing the TreeView. There are Buttons to create a root and to add or delete a node. To the right are the properties of the current node. Here you can rename the node.

Fig. 15.27 TreeNode Editor.

To add nodes programmatically, first create a root node. Create a new TreeNode object and pass it a string to display. Then call method Add to add this new TreeNode to the TreeView’s Nodes collection. Thus, to add a root node to TreeView myTreeView, write


myTreeView.Nodes.Add(new TreeNode(rootLabel));

where myTreeView is the TreeView to which we are adding nodes, and rootLabel is the text to display in myTreeView. To add children to a root node, add new TreeNodes to its Nodes collection. We select the appropriate root node from the TreeView by writing


myTreeView.Nodes[myIndex]

where myIndex is the root node’s index in myTreeView’s Nodes collection. We add nodes to child nodes through the same process by which we added root nodes to myTreeView. To add a child to the root node at index myIndex, write


myTreeView.Nodes[myIndex].Nodes.Add(new TreeNode(ChildLabel));

Class TreeViewDirectoryStructureForm (Fig. 15.28) uses a TreeView to display the contents of a directory chosen by the user. A TextBox and a Button are used to specify the directory. First, enter the full path of the directory you want to display. Then click the Button to set the specified directory as the root node in the TreeView. Each subdirectory of this directory becomes a child node. This layout is similar to that used in Windows Explorer. Folders can be expanded or collapsed by clicking the plus or minus boxes that appear to their left.

Fig. 15.28 Using TreeView to display directory structure.

Alternate View

  1    // Fig. 15.28: TreeViewDirectoryStructureForm.cs
  2    // Using TreeView to display directory structure.
  3    using System;
  4    using System.Windows.Forms;
  5    using System.IO;
  6
  7    namespace TreeViewDirectoryStructure
  8    {
  9       // Form uses TreeView to display directory structure
 10       public partial class TreeViewDirectoryStructureForm : Form
 11       {
 12          string substringDirectory; // store last part of full path name
 13
 14          // constructor
 15          public TreeViewDirectoryStructureForm()
 16          {
 17             InitializeComponent();
 18          }
 19
 20          // populate current node with subdirectories
 21          public void PopulateTreeView(
 22              string directoryValue, TreeNode parentNode)
 23          {
 24             // array stores all subdirectories in the directory
 25             string[] directoryArray =
 26                Directory.GetDirectories(directoryValue);
 27
 28             // populate current node with subdirectories
 29             try
 30             {
 31                // check to see if any subdirectories are present
 32                if (directoryArray.Length != 0)
 33                {
 34                   // for every subdirectory, create new TreeNode,
 35                   // add as a child of current node and recursively
 36                   // populate child nodes with subdirectories
 37                   foreach (string directory in directoryArray)
 38                   {
 39                       // obtain last part of path name from the full path
 40                       // name by calling the GetFileNameWithoutExtension
 41                       // method of class Path
 42                       substringDirectory =
 43                          Path.GetFileNameWithoutExtension(directory);
 44
 45                       // create TreeNode for current directory
 46                       TreeNode myNode = new TreeNode(substringDirectory);
 47
 48                       // add current directory node to parent node
 49                       parentNode.Nodes.Add(myNode);
 50
 51                       // recursively populate every subdirectory
 52                       PopulateTreeView(directory, myNode);
 53                     }
 54                 }
 55             }
 56             catch (UnauthorizedAccessException)
 57             {
 58                parentNode.Nodes.Add("Access denied");
 59             }
 60          }
 61
 62          // handles enterButton click event
 63          private void enterButton_Click(object sender, EventArgs e)
 64          {
 65             // clear all nodes
 66             directoryTreeView.Nodes.Clear();
 67
 68             //   check if the directory entered by user exists
 69             //   if it does, then fill in the TreeView,
 70             //   if not, display error MessageBox
 71             if   (Directory.Exists(inputTextBox.Text))
 72             {
 73                   // add full path name to directoryTreeView
 74                   directoryTreeView.Nodes.Add(inputTextBox.Text);
 75
 76                   // insert subfolders
 77                   PopulateTreeView(
 78                      inputTextBox.Text, directoryTreeView.Nodes[ 0 ]);
 79             }
 80             // display error MessageBox if directory not found
 81             else
 82             {
 83                MessageBox.Show(inputTextBox.Text + " could not be found.",
 84                   "Directory Not Found", MessageBoxButtons.OK,
 85                   MessageBoxIcon.Error);
 86              }
 87          }
 88        }
 89     }

When the user clicks the enterButton, all the nodes in directoryTreeView are cleared (line 66). Then, if the directory exists (line 71), the path entered in inputTextBox is used to create the root node. Line 74 adds the directory to directoryTreeView as the root node, and lines 77–78 call method PopulateTreeView (lines 21–60), which takes a directory (a string) and a parent node. Method PopulateTreeView then creates child nodes corresponding to the subdirectories of the directory it receives as an argument.

Method PopulateTreeView (lines 21–60) obtains a list of subdirectories, using method GetDirectories of class Directory (namespace System.IO) in lines 25–26. Method GetDirectories takes a string (the current directory) and returns an array of strings (the subdirectories). If a directory is not accessible for security reasons, an UnauthorizedAccessException is thrown. Lines 56–59 catch this exception and add a node containing “Access denied ” instead of displaying the subdirectories.

If there are accessible subdirectories, lines 42–43 use method GetFileNameWithout-Extension of class Path to increase readability by shortening the full path name to just the directory name. The Path class provides functionality for working with strings that are file or directory paths. Next, each string in the directoryArray is used to create a new child node (line 46). We use method Add (line 49) to add each child node to the parent. Then method PopulateTreeView is called recursively on every subdirectory (line 52), which eventually populates the TreeView with the entire directory structure. Our recursive algorithm may cause a delay when the program loads large directories. However, once the folder names are added to the appropriate Nodes collection, they can be expanded and collapsed without delay. In the next section, we present an alternate algorithm to solve this problem.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset