Tree View

The TREE-VIEW control presents hierarchical data in a list. This list is indented to show the relationships among the data items. Users can expand or collapse items in the list to view or hide subsidiary items.

Items

In a tree view control, each item in the hierarchical list is identified by an ID that is assigned at the time the element is added to the control. This provides a unique way to identify each item and thus allows for duplicate items at different points in the hierarchy without any confusion. Tree view IDs are declared in COBOL as USAGE POINTER data items.

Tree view controls have a variety of special properties, including the ability to store hidden data with any item and to display bitmaps adjacent to the items. The special property called ITEM is used to identify which item in the hierarchy is to be affected by the property values you provide. Typically, you set the value of the ITEM property to the ID of the item to be acted on, and then you set another property (such as ITEM-TEXT or ENSURE-VISIBLE or HAS-CHILDREN or BITMAP-NUMBER) to assign a value or setting to that item. Note that you must set the value of ITEM before you set the other property value to get the desired results. ITEM is the index for the tree view control (see the MODIFY and INQUIRE statements for a description of indexes).

Parent and Child Relationships

Items in a tree view control are placed within the hierarchical list according to parent and child relationships that you specify. The special property PARENT allows you to specify whether an item is at the top level of the hierarchy (PARENT = 0, the default) or is the child of another item in the hierarchy (PARENT value set to the ID of the parent item).

Another special property of the tree view control, HAS-CHILDREN, enables you to specify whether new child items can be added underneath a specific item in the list. When HAS-CHILDREN = 0 (the default), an item has children only if they are already physically present in the control. This means that no additional child items can be added to that item by the user.

If HAS-CHILDREN is set to a non-zero value (such as HAS-CHILDREN = 1), this indicates that the item identified by the ITEM property is entitled to have child items added. This setting is useful when it is impractical to place all of a tree's items in the control at once (see examples immediately following). In this situation, you populate the highest level of the tree and then use this property to identify which of the top-level items are entitled to have children. Then, when the user expands a particular item, you have the program respond to the MSG-TV-EXPANDING event by adding the appropriate child items to the control. The HAS-CHILDREN property tells the control which items can be expanded.

Adding Child Items

In many cases, it is impractical to fully load a tree view with all of the items it logically contains. For example, if you want to represent every file on a local disk drive in its directory hierarchy, a tree view is a natural way to do this. However, it could take a long time to populate this tree: every file on the entire drive would have to be located. One way to solve this problem is to populate only the top level of the tree at first, and then populate only those sub-levels that the user visits.

To do this, you have to tell the tree view whether an item is entitled to have children when you add the item to the control. If you did not do this, the control would not allow the user to expand that item. You establish the ability to add children to an item by setting the property HAS-CHILDREN to 1 when you add the parent item. For example:

MODIFY TV-1, ITEM-TO-ADD = "Parent Item" 
   GIVING PARENT-1, HAS-CHILDREN = 1

This informs the control that the item has children, even though the children are not physically present in the control.

There are two approaches you can take when managing the children of a particular item. You can add them the first time the parent item expands, and then leave them in the control, or you can add them as the parent expands and delete them when the parent collapses.

Adding Child Items Once

The first approach is to add child items the first time the parent is expanded and then leave them in the control. To code this, respond to the MSG-TV-EXPANDING message by seeing if there are any children of the parent item. If not, add them at this point. A typical event procedure for this would look like this:

TREE-VIEW-EVENT-1.
    EVALUATE EVENT-TYPE
      WHEN MSG-TV-EXPANDING
          IF EVENT-DATA-1 = TVFLAG-EXPAND    |Item expanding
              MODIFY TV-1( EVENT-DATA-2 ), 
                NEXT-ITEM = TVNI-CHILD GIVING ITEM-1
              IF ITEM-1 = NULL               |No children
                PERFORM ADD-CHILDREN
            END-IF
         END-IF
    END-EVALUATE

The paragraph ADD-CHILDREN would do the work needed to add the child items. In this example, EVENT-DATA-1 contains a flag that describes whether the parent item is being expanded or collapsed, and EVENT-DATA-2 contains the ID of the parent item.

Adding Child Items on Each Expansion

The second approach is to add child items each time the parent expands and then remove them when the parent collapses. The code for adding the items is slightly easier because you do not have to guard against adding multiple times. However, you have additional code to handle the removal of the child items. A typical event procedure for this approach looks like this:

TREE-VIEW-EVENT-1.

    EVALUATE EVENT-TYPE
      WHEN MSG-TV-EXPANDING
          IF EVENT-DATA-1 = TVFLAG-EXPAND
             PERFORM ADD-CHILDREN
          END-IF

      WHEN MSG-TV-EXPANDED
          IF EVENT-DATA-1 = TVFLAG-COLLAPSE
             MODIFY TV-1, ITEM-TO-EMPTY = EVENT-DATA-2
          END-IF
Note: It is important that you add the children in response to the MSG-TV-EXPANDING event and remove them in response to the MSG-TV-EXPANDED event. Any other approach can confuse the control and produce odd results.

Navigating a Tree View with the Keyboard

Typically, users use a mouse to interact with a tree view control. However, users can also use the keyboard to accomplish many actions.

The down arrow key selects the next visible item in the tree (that is, moves the selection down one row).

The up arrow key selects the previous visible item in the tree (that is, moves the selection up one row).

If the current item is collapsed (that is, has a plus sign to its left):

  • The right arrow key expands the item
  • The left arrow key selects the parent item

If the current item is expanded (that is, has a minus sign to its left):

  • The right arrow key selects the first child item
  • The left arrow key collapses the item

If the current item has no children:

  • The right arrow key has no effect
  • The left arrow key selects the parent item

The page up (PgUp) and page down (PgDn) keys select items one page minus one item away from the current item.

Editing Label names with the mouse

You can enable users to change the text of a tree-view item. This feature is controlled by the runtime configuration variable TV_EDITLABELS. When this variable is set to "1" (on, true, yes) you can change the value of the tree-view item by clicking it with the mouse (just like with Windows Explorer). When the variable is set to "0" (off, false, no) text changes are not allowed. The default value of TV_EDITLABELS is "0".

To keep track of the changes, two messages are generated from the tree-view to the COBOL program: MSG_TV_BEGINEDITLABEL and MSG_TV_ENDEDITLABEL.

MSG_TV_BEGINEDITLABEL is sent to the COBOL program when the user begins the edit. EVENT-DATA-1 is always 0, and EVENT-DATA-2 contains the handle of the item being modified. The program can prevent the modification by setting EVENT-ACTION to EVEN-ACTION-FAIL.

MSG_TV_ENDEDITLABEL is sent when the user has successfully finished editing. EVENT-DATA-1 is always 0 and EVENT-DATA-2 contains the handle of the modified item.