Add Tree List Box

The Tree List Box class cTreeListBox is used to show a tree structured view of information. A typical usage of the Tree List Box is a master detail layout where the tree list is used as an object browser. 

Figure 1: The picture shows an example where companies are displayed.

Contents

Creating the Tree List Box

  1. Open the form you wish to add the Tree List Box to.
  2. From the Visual Studio Toolbox, drag the cTreeListBox control onto the form.
Usually the Tree List Box is used together with a Resize Splitter to get a movable splitter bar between the Tree List Box and the rest of the content on the form.

Configuring the Tree List Box

  1. In the design area, select the Tree List Box control.
  2. Open the context menu for the Tree List Box and choose "Node Setup..." to open the designer for the Tree List Box node types.

Figure 2: Property editor for the two node types.

There are a few properties that can be set for each node.

Programming the Tree List Box

There is no automatic data bound node enumeration functionality in the cTreeListBox. Setting up the node types is only about the layout. To fill the tree with nodes you have to implement some additional logic. Basically the cTreeListBox will inform the subscriber when a node is selected or activated, the rest is up to the programmer.

Expanding a node

When a node is expanded, PM_TreeListNodeExpand is sent and can be captured on the cTreeListBox. This needs to be implemented in the event handler for WindowActions for the cTreeListBox instance. See how to handle events for more information.

The PM_TreeListNodeExpand message carries the node type of the expanded node and its handle.

The following example message handler for a cTreeListBox instance handles creating a root node and expansion of one node type.

/// <summary>
/// PM_TreeListNodeExpand event handler.
/// </summary>
private void cTreeListBox1_OnPM_TreeListNodeExpand(object sender, WindowActionsEventArgs e)
{
	e.Handled = true;

	cMessage msg = new cMessage();
	SalNumber nFetch = 0;

	cTreeListBox1.TreeListBeginLoad();
 
	switch ((int)e.WParam)
	{
		case Ifs.Fnd.ApplicationForms.Const.TREELIST_NodeTypeRoot:
			msg.Construct();
			msg.AddAttribute("DISPLAYTEXT""All Companies");
			cTreeListBox1.TreeListNodeInsert(0, -1, msg, false);
			break;
 
		case 0:
		
			Ifs.Fnd.ApplicationForms.Var.g_Bind.s[0] = cmbsCompany.Text;
			Ifs.Fnd.ApplicationForms.Var.g_Bind.s[1] = dfsName.Text;
			
			DbPrepareAndExecute(cSessionManager.c_hSql,
			"select COMPANY, NAME from COMPANY order by COMPANY into :g_Bind.s[0], :g_Bind.s[1]");

			while (DbFetchNext(cSessionManager.c_hSql, ref nFetch))
			{
				msg.Construct();
				msg.AddAttribute("COMPANY", sCompany);
				msg.AddAttribute("DISPLAYTEXT", Ifs.Fnd.ApplicationForms.Var.g_Bind.s[0] + " - " + Ifs.Fnd.ApplicationForms.Var.g_Bind.s[1]);
				cTreeListBox1.TreeListNodeInsert(1, e.LParam, msg, true);
			}
			break;
	}
	cTreeListBox1.TreeListEndLoad();
}

Figure 3: Example implementation of a TreeListNodeExpand event handler.

Nodes are added by sending a cMessage structure to the TreeListNodeInsert method. The message can contain any attribute data you wish the node to have. The only mandatory attribute is the chosen Display Attribute that is defined for the node, which is used as node label in the tree.

The TreeListBeginLoad and TreeListEndLoad methods should be used before and after updating the cTreeListBox content, to ensure a good user experience.

Note: You can use the available Code Snippet TreeListNodeExpand in Visual Studio to quickly get the above structure in place as a template.

Node Selection

A node can be selected and/or activated. By traversing the tree structure with the keyboard or using the mouse, the user selects nodes. If a node is double clicked or the enter key is pressed on the keyboard, the node is activated. Typically any detail information should be updated on activation rather than selection. There is no strict design rule here though, and to accommodate different scenarios the PM_TreeListNodeActivate can be captured to modify default behavior. If action needs to be taken on node selection then the design time property Activate Node when Selected should be set:

  1. In the design area, select the Tree List Box control.
  2. In the Visual Studio Properties window, set the Activate Node when Selected to true.

The following two code samples together provide an example of how to capture PM_TreeListNodeActivate in order to take specific action in a corresponding detail. See how to handle events for more information.

/// <summary>
/// Window Actions for cTreeListBox1
/// </summary>
private void cTreeListBox1_WindowActions(object sender, WindowActionsEventArgs e)
{
	switch (e.ActionType)
	{	
		case Const.PM_TreeListNodeActivate:
			this.cTreeListBox1_OnPM_TreeListNodeActivate(sender, e);
			break;
		case Const.PM_TreeListNodeExpand:
			this.cTreeListBox1_OnPM_TreeListNodeExpand(sender, e);
			break;
	}
}

Figure 4: WindowActions method for the PM_TreeListNodeActivate message.

/// <summary>
/// PM_TreeListNodeActivate event handeler.
/// </summary>
private void cTreeListBox1_OnPM_TreeListNodeActivate(object sender, WindowActionsEventArgs e)
{
	e.Handled = true;
 
	// Check if selected node is a site node.
	if ((int)e.WParam == 2)
	{
		cMessage msg = new cMessage();
		if (cTreeListBox1.TreeListNodeGet(e.LParam, msg))
		{
			// Refresh the detail pane of our splitter
			frmSiteDetail.FromHandle(cResizeSplitter1.SplitterGetSecond()).Refresh(msg);
		}
	}
}

Figure 5: Example implementation of the TreeListNodeActivate method where the tree list box is used in a master detail layout.

Manipulating Nodes in the Tree List Box

The Tree List Box also allows "Cut", "Copy" and "Paste" functionality for the nodes in the structure. These operations can be controlled by the design time settings. They are

The first two conditions are to control the operations available on the node type and the third option is used to control the two operations' behavior.

The "Cut", "Copy" and "Paste" options are available from the context menu on the nodes and from the keyboard. The "Cut" and "Paste" function can be performed by a drag-drop operation. The respective messages sent are PM_Cut, PM_Copy and PM_Paste.

The messages contain the following values

When the "Cut" or "Copy" operations are performed the node information is stored in the global variable TreeListBoxCut_Data. The variable is of the type __cCutCopyPasteData. The information in memory can be accessed using the public functions available in cTreeListBox.

The drag-drop functionality is similar to the cut-paste functionality, except for that it is performed without the menu. In the "Copy" and "Paste" function only a record is inserted to the new position.

Modifying the Context Menu

The context menu of a tree list box can be modified, see Create Context Menus.