Home

Characteristics of a Tree View

 

The Path to a Node

After a node has been added to a tree, it holds a position relative to its parent and its existence depends on that parent. To keep track of its "ancestry", each node has a path that can be used to identify its parent and its grand-parent(s), if any. To know the path of a node from itself to the root, you can access its TreeNode.FullPath property. This property produces a string made of sections separated by a specific character identified as the TreeView.PathSeparator property.

By default, this character is the backslash, following the conventions of the operating system. If you want to use a different character or string, assign it to the PathSeparator property. To know what character or string a tree view is using as the separator, you can retrieve the value of its PathSeparator property.

Hot Tracking

In order to select an item, the user must click it or navigate to it using the keyboard. Alternatively, if you want the items to be underlined when the mouse passes over them, set to true the TreeView.HotTracking Boolean property. Its default value is false. Here is an example:

private void InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(242, 320);

        tvwCountries = new TreeView();
        tvwCountries.Location = new Point(12, 12);
        tvwCountries.Width = 210;
        tvwCountries.Height = 100;

        tvwCountries.HotTracking = true;

        Controls.Add(tvwCountries);

        TreeNode[] nodContinents = { new TreeNode("Africa"),
				   new TreeNode("America"),
				   new TreeNode("Asia"),
				   new TreeNode("Europe") };

        TreeNode nodWorld = new TreeNode("World", nodContinents);
        tvwCountries.Nodes.Add(nodWorld);
}

This would produce:

Countries Statistics

The Intermediary Lines of Related Nodes

As mentioned already, a tree view appears as a list of items arranged like a tree. This implies a relationship of parent-child among the items in the control. To indicate this relationship between two nodes, a line is drawn from one to another. Based on this, a line from a node on top of another node under it indicates that the one on top is the parent to the one under it.

The presence or absence of the lines among related nodes is controlled by the TreeView.ShowLines Boolean property. By default, this property is set to true (in the .NET Framework, some other libraries have it set by default to false). If this property is set to false, the lines between the nodes would not display. Here is an example:

private void InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(242, 320);

        tvwCountries = new TreeView();
        tvwCountries.Location = new Point(12, 12);
        tvwCountries.Width = 210;
        tvwCountries.Height = 100;

        tvwCountries.ShowLines = false;

        TreeNode[] nodContinents = { new TreeNode("Africa"),
				   new TreeNode("America"),
				   new TreeNode("Asia"),
				   new TreeNode("Europe") };

        TreeNode nodWorld = new TreeNode("World", nodContinents);
        tvwCountries.Nodes.Add(nodWorld);

        Controls.Add(tvwCountries);
}

This would produce:

Countries Statistics

The Root Lines

If you create a tree that has more than one root, a line is drawn among those root nodes. Here is an example:

Countries Statistics

The presence or absence of this type of line is controlled by the TreeView.ShowRootLines Boolean property.

Node Indentation

Indentation is the ability for a child node to be aligned to the right with regards to its parent. The general distance from the left border of the parent to the left border of the child is partially controlled by the TreeView.Indent property which is an integer. If the default distance doesn't suit you, you can change it by assigning a positive number to the control's Indent property.

Full Row Selection

When the user clicks an item, that node becomes highlighted for the length of its string. If you want, you can show the highlighting on the selected node but from the left to the right borders of the tree view. To do this, you can set the TreeView.FullRowSelect Boolean property to true. Its default value is false. For the TreeView.FullRowSelect property to work, the ShowLines property must be set to false. Here is an example:

private void InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(242, 320);

        tvwCountries = new TreeView();
        tvwCountries.Location = new Point(12, 12);
        tvwCountries.Width = 210;
        tvwCountries.Height = 100;

        tvwCountries.HotTracking = true;
        tvwCountries.ShowLines = false;
        tvwCountries.FullRowSelect = true;

        TreeNode[] nodContinents = { new TreeNode("Africa"),
				   new TreeNode("America"),
				   new TreeNode("Asia"),
				   new TreeNode("Europe") };

        TreeNode nodWorld = new TreeNode("World", nodContinents);
        tvwCountries.Nodes.Add(nodWorld);

        Controls.Add(tvwCountries);
}

This would produce:

Countries Statistics

Hiding Selection After Losing Focus

We saw that, to select an item, the user can click it. If the user clicks another control, the node that was selected in the tree view loses its highlighting because the control has lost focus. When the focus moves to another control, if you want the selected node of the tree view to preserve its highlighting, set to false the TreeView.HideSelection Boolean property. Its default value is true.

The + and - Buttons

At this time, we have seen that some nodes have children and some don't. When a node has at least one child, the node indicates this by displaying a + button. If the user clicks the + button, the node expands, displays a list of its children, and the button becomes -. The presence or absence of the + and - buttons is controlled by the TreeView.ShowPlusMinus Boolean property. By default, this property is set to true. If you don't want the parent nodes to display the + or - button, set this property to false.

Expanding and Collapsing Tree Nodes

When a node displays a + button and the user clicks that button, the node displays its child(ren). This action is referred to as expanding the node. To programmatically expand a node, call its TreeNode.Expand() method. Its syntax is:

public void Expand();

This method only expands the node that calls it but if its children have their own children, they are not expanded.  To expand a node and its children that have nodes, you can call its TreeNode.ExpandAll() method. Its syntax is:

public void ExpandAll();

To find out if a node is expanded, check the value of its TreeNode.IsExpanded property.

To expand other nodes of the tree view, the user can continue clicking each node that has a + button as necessary. To programmatically expand all nodes of a tree view, call its TreeView.ExpandAll() method. Its syntax is:

public void ExpandAll();

If a node is displaying a - button, it indicates that it is showing the list of its children. To hide the list, the user can click the - button. This action is referred to as collapsing the node. To programmatically collapse a node, call its TreeNode.Collapse() method whose syntax is:

public void Collapse();

The user can do this for each node that is expanded. To programmatically collapse all nodes of a tree view, call its TreeView.CollapseAll() method. Its syntax is:

public void CollapseAll();

Tree Nodes and Check Boxes

Besides the strings (and some small pictures as we will see later), the nodes of a tree view can display a check box on their left side. The presence or absence of the check box is controlled by the CheckBoxes Boolean property whose default value is false. If you want to display the check boxes, set this property to true. Here is an example:

private void InitializeComponent()
{
        Text = "Countries Statistics";
        Size = new Size(242, 320);

        tvwCountries = new TreeView();
        tvwCountries.Location = new Point(12, 12);
        tvwCountries.Width = 210;
        tvwCountries.Height = 100;

        tvwCountries.CheckBoxes = true;

        TreeNode[] nodContinents = { new TreeNode("Africa"),
				   new TreeNode("America"),
				   new TreeNode("Asia"),
				   new TreeNode("Europe") };

        TreeNode nodWorld = new TreeNode("World", nodContinents);
        tvwCountries.Nodes.Add(nodWorld);

        Controls.Add(tvwCountries);
}

This would produce:

Countries Statistics

If you equip the nodes with check boxes, the user can click an item to select it independently of the check box. The user can also click the check box, which would place a check mark in the box. To programmatically check the box, you can assign a true value to the node's Checked property.

When a check mark has been placed in a node's check box, the tree view fires an AfterCheck event, which is handled by the TreeViewEventHandler delegate. The AfterCheck event is carried by the TreeViewEventArgs class. One of properties of this class is called Action, which specifies why or how the event occurred. The Action property is in fact a value based on the TreeViewAction enumerator. Its members are:

ByKeyboard: This indicates that the event was fired by pressing a key

ByMouse: This indicates that the event was fired based on an action on the mouse

Collapse: This indicates that event was fired when the tree collapsed

Expand: This indicates that the event was fired when the tree expanded

Unknown: None of the above reasons caused the event, but the event was fired

The other property of the TreeViewEventArgs class is called Node. This member is of type TreeNode. It carries a reference to the node that fired the event, whether it was clicked, checked, expanded, or collapsed.

To programmatically find out if a node is checked, check the value of its Checked property.

Tree Nodes and Icons

Each of the nodes we have used so far displayed a simple piece of text. To enhance the appearance of a node, besides its text, you can display a small icon to the left of its string. To do this, you must first create an ImageList control and assign it to the TreeView.ImageList property.

When creating a node, if you plan to display an icon next to it, you can use the following constructor of the TreeNode class:

public TreeNode(String text, int imageIndex, int selectedImageIndex);

This constructor allows you to specify the text that the node will display, the index of the picture it will use in the ImageList property, and the picture it will display when it is selected.

If you are creating a node with its children and you want to specify its pictures, use the following constructor of the TreeNode class:

public TreeNode(string text,
                            int imageIndex,
                            int selectedImageIndex,
                            TreeNode children[]);

Just as done previously, after defining the TreeNode object, you can add it to the tree by passing it to the TreeNodeCollection.Add() method. In the same way, you can create an array of TreeNode objects and pass it to the TreeNodeCollection.AddRange() method.

Practical LearningPractical Learning: Associating Icons With Nodes

  1. To create an icon, on the main menu, click Project -> Add New Item...
  2. In the Templates list, click Icon File
  3. Set the Name to cpap1 and click Add
  4. Right-click the white area and click Delete Image Type
  5. Design the 16x16, 16 colors version of the icon as follows:
     
  6. On the main menu, click File -> Save cpap1.ico
  7. On the main menu, click File -> Close
  8. On the main menu, click Project -> Add New Item...
  9. In the Templates list, click Icon File
  10. Set the Name to cpap2 and click Add
  11. Right-click the white area and click Delete Image Type
  12. Design the 16x16, 16 colors version of the icon as follows:
     
  13. On the main menu, click File -> Save cpap2.ico
  14. On the main menu, click File -> Close
  15. On the main menu, click Project -> Add New Item...
  16. In the Templates list, click Icon File
  17. Set the Name to year1 and click Add
  18. Right-click the white area and click Delete Image Type
  19. Design the 16x16, 16 colors version of the icon as follows:
     
  20. On the main menu, click File -> Save make2.ico
  21. On the main menu, click File -> Close
  22. On the main menu, click Project -> Add New Item...
  23. In the Templates list, click Icon File
  24. Set the Name to year2 and click Add
  25. Right-click the white area and click Delete Image Type
  26. Design the 16x16, 16 colors version of the icon as follows:
     
  27. On the main menu, click File -> Save year2.ico
  28. On the main menu, click File -> Close
  29. On the main menu, click Project -> Add New Item...
  30. In the Templates list, click Icon File
  31. Set the Name to make1 and click Add
  32. Right-click the white area and click Delete Image Type
  33. Design the 16x16, 16 colors version of the icon as follows:
     
    Icon Design: Diamond
  34. On the main menu, click File -> Save make1.ico
  35. On the main menu, click File -> Close
  36. On the main menu, click Project -> Add New Item...
  37. In the Templates list, click Icon File
  38. Set the Name to make2 and click Add
  39. Right-click the white area and click Delete Image Type
  40. Design the 16x16, 16 colors version of the icon as follows:
     
    Icon Design: Diamond
  41. On the main menu, click File -> Save make2.ico
  42. On the main menu, click File -> Close
  43. On the main menu, click Project -> Add New Item...
  44. In the Templates list, click Icon File
  45. Set the Name to model1 and click Add
  46. Right-click the white area and click Delete Image Type
  47. Design the 16x16, 16 colors version of the icon as follows:
     
  48. On the main menu, click File -> Save model1.ico
  49. On the main menu, click File -> Close
  50. On the main menu, click Project -> Add New Item...
  51. In the Templates list, click Icon File
  52. Set the Name to model2 and click Add
  53. Right-click the white area and click Delete Image Type
  54. Design the 16x16, 16 colors version of the icon as follows:
     
  55. On the main menu, click File -> Save model2.ico
  56. On the main menu, click File -> Close
  57. On the main menu, click Project -> Add New Item...
  58. In the Templates list, click Icon File
  59. Set the Name to category1 and click Add
  60. Right-click the white area and click Delete Image Type
  61. Design the 16x16, 16 colors version of the icon as follows:
     
  62. On the main menu, click File -> Save category1.ico
  63. On the main menu, click File -> Close
  64. On the main menu, click Project -> Add New Item...
  65. In the Templates list, click Icon File
  66. Set the Name to category2 and click Add
  67. Right-click the white area and click Delete Image Type
  68. Design the 16x16, 16 colors version of the icon as follows:
     
    Icon Design: Minus
  69. On the main menu, click File -> Save category2.ico
  70. On the main menu, click File -> Close
  71. Display the form.
    In the Toolbox, click ImageList and click the form
  72. In the Properties window, click (Name) and type imgAutoParts
  73. Click the ellipsis button of the Images field
  74. In Image Collection Editor, click Add
  75. Locate the folder that contains the icons you created and display it in the Look In combo box
  76. Select cpap1.ico and click Open
  77. In the same way, add the other pictures in the following order: cpap2.ico, year1.ico, year2.ico, make1.ico, make2.ico, model1.ico, model2.ico, category1.ico, and category1.ico
     
    Image Collection Editor
  78. Click OK
  79. On the form, click the tree view
  80. In the Properties window, click ImageList, then click the arrow of its combo box and select imgAutoParts
  81. Access the Central.cs source file and change the code of the Load event as follows:
     
    private void Central_Load(object sender, EventArgs e)
    {
                TreeNode nodRoot = tvwAutoParts.Nodes.Add("College Park Auto-Parts",
                                                          "College Park Auto-Parts", 0, 1);
    
                . . . No Change
    
                // Showing the years nodes
                for (int years = DateTime.Today.Year + 1; years > 1960; years--)
                    nodRoot.Nodes.Add(years.ToString(), years.ToString(), 2, 3);
    
                // Expand the root node
                tvwAutoParts.ExpandAll();
    
                // Showing the makes nodes
                foreach (TreeNode nodYear in nodRoot.Nodes)
                {
                    ArrayList lstMakes = new ArrayList();
    
                    foreach (PartDescription part in parts)
                    {
                        if (nodYear.Text == part.CarYear.ToString())
                        {
                            if (!lstMakes.Contains(part.Make))
                                lstMakes.Add(part.Make);
                        }
                    }
    
                    foreach (string strMake in lstMakes)
                        nodYear.Nodes.Add(strMake, strMake, 4, 5);
                }
    
                // Showing the models nodes
                foreach (TreeNode nodYear in nodRoot.Nodes)
                {
                    foreach (TreeNode nodMake in nodYear.Nodes)
                    {
                        ArrayList lstModels = new ArrayList();
    
                        foreach (PartDescription part in parts)
                        {
    
                            if ((nodYear.Text == part.CarYear.ToString()) &&
                                (nodMake.Text == part.Make))
                            {
                                if (!lstModels.Contains(part.Model))
                                    lstModels.Add(part.Model);
    
                            }
                        }
    
                        foreach (string strModel in lstModels)
                            nodMake.Nodes.Add(strModel, strModel, 6, 7);
                    }
                }
    
                // Showing the categories nodes
                foreach (TreeNode nodYear in nodRoot.Nodes)
                {
                    foreach (TreeNode nodMake in nodYear.Nodes)
                    {
                        foreach (TreeNode nodModel in nodMake.Nodes)
                        {
                            ArrayList lstCategories = new ArrayList();
    
                            foreach (PartDescription part in parts)
                            {
    
                                if ((nodYear.Text == part.CarYear.ToString()) &&
                                    (nodMake.Text == part.Make) &&
                                    (nodModel.Text == part.Model))
                                {
                                    if (!lstCategories.Contains(part.Category))
                                        lstCategories.Add(part.Category);
                                }
                            }
    
                            foreach (string strCategory in lstCategories)
                                nodModel.Nodes.Add(strCategory, strCategory, 8, 9);
                        }
                    }
                }
    
                tvwAutoParts.SelectedNode = nodRoot;
    }
  82. Execute the application to test it
  83. Close the form and return to your programming environment
College Park Auto-Parts

Previous Copyright © 2007 FunctionX, Inc. Home