Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Articles
Search: 

Using the Treeview Control
Cetin Basoz, June 1, 2001
Introduction Any data that could be represented in an hierarchical way is a candidate for a treeview listing. This article will show you how to use the MS Active X treeview control in your own applications in a simple way, populate it fast and apply drag&drop to it. Note that this control is ...

Introduction

Any data that could be represented in an hierarchical way is a candidate for a treeview listing. This article will show you how to use the MS Active X treeview control in your own applications in a simple way, populate it fast and apply drag&drop to it. Note that this control is not included in the ActiveX controls list by default, so you will need to add it via the ‘Tools\Options\Controls’ menu. While working with the treeview control you can press ‘F1’ to get help about its properties, events, and methods. As with other VFP objects, you can right click on this control and select ‘Treeview control properties’ to get the property pages dialog box. In this article we will refer to the MS Active X treeview control as simply the OleTreeview.

The Basics

Treeview data in its simple form is much like a 3 columns table. Each node has a unique key identifying itself (NodeKey - Primary Key), link to parent node (ParentKey - Foreign Key) and text that user sees (NodeText).

Tables 1 and 2 show how treeview data table might look like if it were a directory listing or data listing. Treeview samples for these are shown in Figures 1 and 2.

Treeview Methods

To add a new node, use this method:

OleTree.Nodes.Add(cParentKey, tvwChild, cNodeKey, cNodeText, cImage1, cImage2)

Syntax:
object.Add(relative, relationship, key, text, image, selectedimage)

Note that cImage1 and cImage2 are optional even though syntax says ‘selectedimage’ for the second it’s actually ‘expandedimage’ and shows when item is expanded ( e.g.: Open Folder in explorer).

Here are the constants used in the node add:

#Define tvwFirst    0
#Define tvwLast     1
#Define tvwNext     2
#Define tvwPrevious 3
#Define tvwChild    4
If the node is you are adding is the root node then simply omit ‘cParentKey’ and use this format:
OleTree.Nodes.Add(, tvwFirst, cNodeKey, cNodeText, cImage1, cImage2)
To remove a node:
OleTree.Nodes.Remove(nIndex)
To seek a node:

OleTree.Nodes(nIndex) or  OleTree.Nodes(cNodeKey)

To place a node before a node use tvwPrevious :

OleTree.Nodes.Add(loTarget.Key, tvwPrevious, lcSourceKey, lcSourceText)

Populating Nodes

The disadvantage of the OleTreeview is that it is slow. Think of a treeview control that would be populated with drive and directory list like Windows Explorer’s left pane. Even if the node collection was ready for it to fill, it would take ages to populate the treeview. Add time to collect directory structure and it’s dog slow. The same goes with data showing in treeview.

To solve this issue think of a treeview as a kind of a pageframe. It’s a well-known trick to save page contents in a pageframe as classes and instantiate them only on first visit to the page. Use the same approach with a treeview control by showing only when needed. Logic goes like this :

  1. Add root nodes.
  2. As adding each node check if it would have any children.
  3. If yes then simply add a child node with a key like ‘dummy’ added to original node key (this would provide + sign).
  4. When a node is expanded check child’s key.
  5. If child key is NodeKey+ ‘dummy’ then next level needs populating.
  6. Remove the child with key Nodekey+ ‘dummy’ (or you might change key and text).
  7. Add child level nodes.
  8. Repeat steps 2-3 for newly added nodes.

I mentioned you could use any data that could be expressed in an hierarchical way in a treeview. Well right, but drive & directory listing best resembles a treeview hierarchical structure. For this reason I’ll use directory listing in my code samples (I think treeview like data display is actually another set of ActiveX controls’ job and hope to talk about this in a future issue).

Comments about code

Besides Treeview control sample code uses ImageList ActiveX control to provide node images (folder, drive, CDRom etc) and Sripting.FileSystemObject as well.

  • FileSystemObject’s drives collection is browsed first to collect drives on system
  • IsReady property checked for drive being ready
  • If ready then RootPath property is used to get drive’s root path
  • FillTree custom method is called with provided root path.
  • When a node is expanded Node.Fullpath is used to get fullpath to directory
  • _Subfolders custom method is called with the provided fullpath to fill-in sub nodes (folders)

When you drag&drop a node with no shift identifier key than it’s assumed as either a reorder (parent same) or copy. Using ‘shift’ signals a move and ‘ctrl’ a copy operation. In a copy operation with same parent or move what we do is :

  • Remove the node
  • Add node before target node

If it’s a reordering than we also call _Subfolders method to set + sign if has children.

Normally it would be done in all operations but remember here I’m just demonstrating with existing folders and not doing a physical copy, move on disk. Also I must warn you about the logic in copy, move, reordering that I was lazy not to do it bulletproof. Just consider it does its job as a sampling on Treeview drag&drop. As a last note if you want to drag&drop to or from VFP native controls then you need to use OLEDrag, OLEDragDrop methods which are available in VFP6 and up. If you use a prior version also note that DropHighLight calls are expected to be problematic if OCX version is not SP4.

OK I hear you say let’s see code and here it is: Treeview.zip

Cetin Basoz, Engineerica Inc.
Çetin is Engineerica's lead developer and also administering "Institute of Marine Sciences and Technology-Izmir" computer division. He specializes in using Visual FoxPro, .NET and SQL server. He is using Foxbase, Foxpro and Visual FoxPro since 80's, .NET since 2004. He has been a Microsoft MVP 1999-2010. His expertise has been used in prototyping, development, training and testing. Now he continues his carrier on VFP and C#.Net doing mostly Silverlight RIA applications. Though Çetin is well known for his programming skills, very few people know that he is also a licensed Medical Doctor. After practicing medicine for about ten years Çetin switched careers and went to his true passion - software programming.
More articles from this author
Cetin Basoz, September 20, 2000
This will get you the RGB equivalent from a color number. These are 2 little functions doing it different ways. You may try which one fits better your needs. The first one uses the 256 syntax to get the color. The second one is using the BITAND and BITRSHIFT approach.
Cetin Basoz, August 9, 2000
With grids it's a little problematic to show different images or container objects per row. You might have only image filenames stored in a table or you might want to show something like a time table with shape controls where you only store start-end values as numeric. Grid shows the same thing on a...
Cetin Basoz, February 16, 1998
Here is two sample functions one is just for using wordbasic and the second is using wordbasic in mailmerge. Wordbasic PEMs are defined in wrdbasic.hlp located in winword directory. This help file contains the arguments as named arguments which are not suitable for calling via VFP. In files section...
Cetin Basoz, April 26, 2001
Well it started when I found it hard to check rtf files for MSDN subscription index. In last few shipments there were also an MDB in 'UN-SUPPED' directory but my Access is too perfect to use an MDB so I decided to get Access data to VFP tables.
Cetin Basoz, January 6, 1998
Databases have a little different header from tables thus making it impossible to copy them online through SQL or "copy to". The code below accomplishes this opening the DBC readonly and creating a copy of it using lowlevel IO.