Search the Catalog
Visual Basic Controls in a Nutshell

Visual Basic Controls in a Nutshell

By Evan S. Dictor
1st Edition July 1999
1-56592-294-8, Order Number: 2948
762 pages, $24.95

Sample Chapter 5 Controls

TreeView Control

The TreeView control is a hierarchical list of related Node objects. The user can expand and collapse these node families easily while navigating through the control; depicting the trees and expanding and contracting the nodes are handled automatically by the TreeView control itself. An example of a TreeView control used in an application is the Windows Explorer program, where the TreeView occupies the left side of the form.

Tip: The TreeView control is contained in the Windows Common Controls (COMCTL32.OCX ) that come with Visual Basic Professional and Enterprise editions.

Control Tasks

The following categories reflect the tasks that are executed when creating a TreeView.

Set Properties

  1. Set general appearance.
  2. Style
    There are eight variations to the appearance of the TreeView. Basically, they control whether there are pictures, plus and minus symbols, and lines. The following table, as well as Figure 5-58, show how each value for the Style property affects the look of the TreeView:

    Constant

    Value

    Description

    tvwTextOnly

    0

    Only the text is displayed.

    tvwPictureText

    1

    The text and images are displayed.

    tvwPlusMinusText

    2

    The text and a plus or minus symbol are displayed.

    tvwPlusPictureText

    3

    The text, image, and a plus or minus symbol are displayed.

    tvwTreelinesText

    4

    The text and lines are displayed.

    tvwTreelines-PictureText

    5

    The text, image, and lines are displayed.

    tvwTreelines-PlusMinusText

    6

    The text, plus or minus symbols, and lines are displayed.

    tvwTreelinesPlus-MinusPictureText

    7

    The text, image, plus or minus symbols, and lines are displayed. This is the default value.

     
    Figure 5-58. The Style property of the TreeView control

     

    LineStyle
    When the Style selected includes lines, the LineStyle property controls whether the lines start at the top-level nodes (0-tvwTreeLines) or at the root above the top-level nodes (1-tvwRootLines). Figure 5-59 shows how the value of the LineStyle property affects the appearance of the TreeView control.
     
    Figure 5-59. The LineStyle property of the TreeView control

     

    Indentation
    The width by which each new child node is indented from its parent node.
    ImageList
    The name of an ImageList control on the same form as the TreeView. Each node placed in the ListView can choose which image to use from the ImageList.
    LabelEdit
    By default, the Text property of each node can be edited by the user simply by clicking on the caption of the selected node. In this case, the LabelEdit property is set to 0-tvwAutomatic. When set to 1-tvwManual, the caption can be edited by the user only after the StartLabelEdit method is called.

  3. Sort the TreeView.
  4. Sorted
    Because of its hierarchical nature, the TreeView itself cannot really be sorted. However, when the Sorted property is set to True, all Node objects with the same parent node are sorted alphabetically. This is a global property that affects all nodes in the TreeView; each node, however, also has a Sorted property that controls whether its child nodes are sorted.

  5. Create Nodes.
  6. Nodes (collection), Node (object)
    Each item in a TreeView is a Node object and therefore is part of the Nodes collection. Node objects cannot be created at design time. At runtime, they can be created by using the Add method of the Nodes collection. This also allows the program to set some of the node's properties. Its syntax is:

    objNodes.Add(relative, relationship, key, text, _

    image, selectedimage)

    All of these arguments except key are discussed in the following section, "Set node properties." key represents a unique string by which a reference to the node can be retrieved from the Nodes collection's Item property.

  7. Set node properties.
  8. Text, Image, SelectedImage
    The caption of the node and the index or key of the ListImage to use for both unselected and selected nodes can be set either as parameters of the Nodes collection's Add method or by assigning values to these properties.
    Relative, Relationship
    These are not actually properties. However, as parameters of the Nodes collection's Add method, they are used to position the new node in the TreeView and therefore to set properties. When you are adding a node, Relative represents another node that is somehow related to the node being added. Relationship denotes how the two nodes are related. When the Relationship parameter is set to 0-tvwFirst, 1-tvwLast, 2-tvwNext, or 3-tvwPrevious, the new node is placed at the same level as the Relative node (i.e., both have the same parent), but either as the first or last node at that level or just after or just before the Relative node, respectively. When set to 4-tvwChild, the new node becomes a child node of the Relative node. Note that when adding a child node, you can choose between defining it in relationship to its parent or to the other child nodes.
    Expanded
    When the Expanded property is set to True, any child nodes are revealed. When set to False, they are hidden.
    ExpandedImage
    Optionally, a node can display a different image when it is expanded than when it is collapsed. The Index or Key of the desired ListImage in the related ImageList can be used in the ExpandedImage property.

  9. Determine the selected node.
  10. SelectedItem (TreeView control), Selected (Node object)
    The SelectedItem property of the TreeView returns the currently selected Node object. The Selected property of a Node object returns a Boolean value indicating whether that node is currently selected. By retrieving the SelectedItem property or iterating the Nodes collection and examining each Node object's Selected property, you can determine which node is selected. By assigning a new Node object to the SelectedItem property or by assigning True to a Node object's Selected property, you can change the selected node programmatically.

  11. Navigate the TreeView's trees.
  12. Typically, in response to a user action such as a click, it is necessary for your application to navigate to or from the current node. This can be done with the following properties:

    Parent
    The Node object's Parent property returns the node that is above the current node in the hierarchy. When you are changing this property to a new node, all child nodes of the node being changed remain connected. Any change that would result in a node becoming its own descendant will rip a hole in the time-space continuum (or cause an error).
    Root
    The Node object's Root property returns the node that is the topmost in the node's hierarchy.
    FullPath
    Provides the full path from the top-level node to the referenced node. The path separator used to delimit individual nodes is defined by the TreeView control's PathSeparator property; its default value is a backslash (\).
    Children, Child
    The Children property of a node returns its number of child nodes. The Child property returns the first child node. If the Child property is referenced for a node with no child nodes, an error will occur. Therefore, you should always check the Children property first.
    FirstSibling, LastSibling, Next, Previous
    Each of these properties returns a node at the same level as the node being referenced. The node returned is denoted by the property name. These properties are useful for "walking" through nodes at the same level, as in this example:
    Private Sub tvwMain_DblClick()
        Dim nodItem As Node
        
        If Me.tvwMain.SelectedItem.Children > 0 Then
            'Check for children nodes.
            Set nodItem = Me.tvwMain.SelectedItem.Child
            'Get first child node.
            Do
                Debug.Print nodItem.Text
                If nodItem = nodItem.LastSibling Then
                    'This is the last node.
                    Exit Do
                Else
                    'Get the next node.
                    Set nodItem = nodItem.Next
                End If
            Loop
        End If
    End Sub

Figure 5-60 displays a TreeView control with six node objects. Some of the relationships between the nodes include the following:

Useful Methods

HitTest
When provided with x and y coordinates, the HitTest method will return a Node object if there is one at those coordinates. Otherwise, Nothing will be returned. The syntax of HitTest is:
Function HitTest(X As Single, Y As Single) As Node
StartLabelEdit
When the StartLabelEdit method is called, the caption of the node becomes both editable by the user and selected. This is unnecessary when the LabelEdit property is set to tvwAutomatic.

Write Event Handlers

Expand, Collapse
When a node is expanded or collapsed, whether through code or by the user, the Expand or Collapse event is fired. This is fired after the node has been visibly expanded or collapsed. However, the Expanded property can be used to reverse this action, as in this example:
Private Sub tvwMain_Expand(ByVal Node As ComctlLib.Node)
    If Node.Tag = "Do Not Expand" Then
        'The Tag property would have been set earlier.
        Node.Expanded = False
    End If
End Sub
ItemClick
When a node is clicked by the user, the NodeClick event is fired. This event also passes the clicked node as a parameter to the event handler.

Example

The following example uses many of the conventions mentioned in this section. Figure 5-61 shows the form produced by this code.

Option Explicit
 
'For this example, create the following controls: _
   a TextBox named txtTotal with the MultiLine _
       property set to True and the Alignment _
       property set to vbRightJustify, _
   an ImageList named imlIcons, and _
   a TreeView named tvwMain.
    
Dim WithEvents lstMain As ListBox
 
Private Sub Form_Load()
    Dim imgVar As ListImage
    
    'We don't want the user to edit the total in _
    the TextBox
    Me.txtTotal.Locked = True
    
    Set lstMain = Me.Controls.Add("vb.listbox", _
                  "lstMain", Me)
    lstMain.Visible = True
    
    'Set up ImageList for Icons
    Me.imlIcons.ImageHeight = 32
    Me.imlIcons.ImageWidth = 32
    Set imgVar = Me.imlIcons.ListImages.Add _
        (1, "food", LoadPicture("Food.ico"))
    Set imgVar = Me.imlIcons.ListImages.Add _
        (2, "burger", LoadPicture("Burger.ico"))
    Set imgVar = Me.imlIcons.ListImages.Add _
        (3, "pizza", LoadPicture("Pizza.ico"))
    Set imgVar = Me.imlIcons.ListImages.Add _
        (4, "sides", LoadPicture("Sides.ico"))
    Set imgVar = Me.imlIcons.ListImages.Add _
        (5, "drinks", LoadPicture("Drinks.ico"))
    Set imgVar = Me.imlIcons.ListImages.Add _
        (6, "dessert", LoadPicture("Dessert.ico"))
    
    'Set up TreeView
    Me.tvwMain.Style = tvwTreelinesPlusMinusPictureText
    'This is actually the default
    Me.tvwMain.ImageList = imlIcons
    
    GetFoodRecords
    
    Me.Caption = "Restaurant"
    Me.Height = 3600
    Me.Width = 5175
End Sub
 
Private Sub Form_Resize()
   If Me.ScaleHeight < 1000 Or Me.ScaleWidth < 1000 Then
      Exit Sub
   End If
    
    Me.tvwMain.Move _
        120, _
        120, _
        Me.ScaleWidth * 0.6 - 180, _
        Me.ScaleHeight - 240
    lstMain.Move _
        Me.ScaleWidth * 0.6 + 60, _
        120, _
        Me.ScaleWidth * 0.4 - 180, _
        Me.ScaleHeight - 655
    Me.txtTotal.Move _
        Me.ScaleWidth * 0.6 + 60, _
        Me.ScaleHeight - 435, _
        Me.ScaleWidth * 0.4 - 180, _
        315
End Sub
 
Private Sub tvwMain_DblClick()
    Dim sItem As String
    
   'Since the dbl-click can occur when the user wants _
   to expand a node, we have to distinguish _
   between that and double-clicking a product.
   If Me.tvwMain.SelectedItem.Children > 0 Then
      'This node has children, so we ignore the _
      dbl-click
      Exit Sub
   Else
      'This node doesn't have children, so we process _
      it as a sale
      sItem = Me.tvwMain.SelectedItem.Text & _
          vbTab & Format$(Me.tvwMain.SelectedItem.Tag, _
          "##0.00")
      lstMain.AddItem sItem
      Me.txtTotal.Text = Val(Me.txtTotal.Text) + _
                  Val(Me.tvwMain.SelectedItem.Tag)
   End If
End Sub
 
Private Sub GetFoodRecords()
   Dim nodItem As Node
    
   'Normally we'd get this information from a _
   database, but for this example we'll create the _
   data by hand. I'm using the Tag property of a node _
   to store the price.
   Set nodItem = Me.tvwMain.Nodes.Add _
        (, , "Top", "Select Item", "food")
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("Top", tvwChild, "BurgerTop", "Burgers", _
        "burger")
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("BurgerTop", tvwChild, , "Hamburger", "burger")
   nodItem.Tag = 1.99
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("BurgerTop", tvwChild, , "Double Burger", _
        "burger")
   nodItem.Tag = 2.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("BurgerTop", tvwChild, "TEST", _
        "Burger Deluxe", "burger")
   nodItem.Tag = 2.99
    
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("Top", tvwChild, "PizzaTop", "Pizza", "pizza")
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("PizzaTop", tvwChild, , "Personal Pizza", _
        "pizza")
   nodItem.Tag = 2.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("PizzaTop", tvwChild, , "10 Inch Pizza", _
        "pizza")
   nodItem.Tag = 5.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("PizzaTop", tvwChild, , "12 Inch Pizza", _
        "pizza")
   nodItem.Tag = 7.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("PizzaTop", tvwChild, , "Super Family Pizza", _
        "pizza")
   nodItem.Tag = 9.99
 
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("Top", tvwChild, "SidesTop", "Sides", "sides")
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("SidesTop", tvwChild, , "Small Fries", "sides")
   nodItem.Tag = 0.99
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("SidesTop", tvwChild, , "Large Fries", "sides")
   nodItem.Tag = 1.39
   Set nodItem = Me.tvwMain.Nodes.Add _
       ("SidesTop", tvwChild, , "Garlic Bread", "sides")
   nodItem.Tag = 0.99
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("SidesTop", tvwChild, , "Side Salad", "sides")
   nodItem.Tag = 0.99
 
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("Top", tvwChild, "DrinksTop", "Drinks", _
        "drinks")
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DrinksTop", tvwChild, , "Cola Soda", "drinks")
   nodItem.Tag = 1.09
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DrinksTop", tvwChild, , "Diet Cola Soda", _
        "drinks")
   nodItem.Tag = 1.09
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DrinksTop", tvwChild, , "Lemon/Lime Soda", _
        "drinks")
   nodItem.Tag = 1.09
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DrinksTop", tvwChild, , "Domestic Beer", _
        "drinks")
   nodItem.Tag = 2.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DrinksTop", tvwChild, , "Red/White Wine", _
        "drinks")
   nodItem.Tag = 2.99
 
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("Top", tvwChild, "DessertTop", "Dessert", _
        "dessert")
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DessertTop", tvwChild, , "Apple Pie Slice", _
        "dessert")
   nodItem.Tag = 2.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DessertTop", tvwChild, , "Cheesecake Slice", _
        "dessert")
   nodItem.Tag = 2.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DessertTop", tvwChild, , "Ice Cream Cone", _
        "dessert")
   nodItem.Tag = 1.49
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DessertTop", tvwChild, , "Hot Fudge Sundae", _
        "dessert")
   nodItem.Tag = 2.99
   Set nodItem = Me.tvwMain.Nodes.Add _
        ("DessertTop", tvwChild, , "Asst Fruit Cup", _
        "dessert")
   nodItem.Tag = 0.99
 
   'Expand the top level node
   Me.tvwMain.Nodes("Top").Expanded = True
End Sub
 
Figure 5-61. TreeView example

 

Interactions

Action

Result

A node is expanded or collapsed either through code (by settings its Expand property) or by the user.

The Expand or Collapse event is fired.

User clicks on the caption of the selected node. LabelEdit property is set to tvwAutomatic.

BeforeLabelEdit event is fired.

User finishes editing the caption.

AfterLabelEdit event is fired.

Back to: Visual Basic Controls in a Nutshell


oreilly.com Home | O'Reilly Bookstores | How to Order | O'Reilly Contacts
International | About O'Reilly | Affiliated Companies | Privacy Policy

© 2001, O'Reilly & Associates, Inc.