The last two ActiveX controls we’re going to explore in this chapter are among the more advanced ones, and they are certainly more difficult to program than the Previous ones. If you’re new to Visual Basic or programming, you may find this material over your head. You can safely skip the rest of this chapter and come back to it after you’ve learned more about Visual Basic and familiarized yourself with the topic of object programming. The two controls discussed in this section, however, are the basic makings of unique applications, as you’ll see in the examples.
The TreeView and ListView controls implement two of the more advanced date structures (a topic that’s not terribly popular even among computer science students). These controls were designed to hide much of the complexity of the data structures they implement, and they do this very well. However, they are more difficult to use than the other controls.
I will start with a general discussion of the two controls to help you understand what they do and when to use them. A basic understanding of the data structures they implement is also required to use them efficiently in your applications. Then. I’ll discuss their members and demonstrate how to use the controls. If you find the examples too difficult to understand, you can always postpone the use of these controls in your .applications. Some of the code I will present in this chapter can be used as is in many situations, so you should take a look at the examples and see if you can incorporate them in your applications.
you learned that the ListBox control is a simple control for store.string items. The items of a ListBox control can be sorted, but they don’t have an’ particular structure. I’m sure most of you wish the List;Boxcontrol had more “features,” such as the means to store structured items or additional information an with each item and display them at will. For instance, a list with city and state names should be structured so that each city appears under the corresponding state name In a ListBox control, you can indent some of the entries, but the control itself can impose or maintain any structure on ‘its data. The answer to the shortcomings of tr ListBox control can be found in the Treeview and ListView controls.
It shows the TreeView and ListView controls used in tandem. What you see is the Windows Explorer, a utility for examining and navigating your hard disk’s structure. The Left pane, where the folders are displayed, is a TreeView. The folder names are displayed in a manner that reflects their structure. . on the hard disk. You can expand and contract certain branches and view only the segment(s) of the tree structure you’re interested in.
The right pane is a ListView control. The items on the ListView control can be displayed in four-different ways (Icons, Small Icons, List, or Report). Although most people prefer to look at the contents of the folders as icons, the most useful view is the Report view, which displays not only filenames, but their attributes as well. In the Report view, the list can be sorted according to any of its columns, making it very easy for the user to locate any item based on various criteria (mtype, size, creation date, and so on).
How Tree Structures Work
The TreeView control implements a data structure known as a tree. A tree is the most appropriate structure for storing hierarchical information. The organizational chart of most companies is a tree structure. Every person reports to another person above them, all the way to the president or CEO depicts a possible organization of continents, countries, and cities as a tree. Every city belongs to a country and every country to a continent. In the same way, every computer me belongs to a folder that may belong to an even bigger folder. You can’t draw large tree structures on paper, but it’s possible to create a similar structure in the computer’s memory without size limitations.
Each item in the tree is called a node, and nodes can be nested to any level. Oddly, the top node is the root of the tree and the subordinate nodes are . called child nodes. If you try to visualize this structure as a real tree, think of it as an upside-down tree with the branches emerging from the root.
To locate a city,you must start at the root node and select the continent to which the city belongs. Then, you must find the country in the selected continent to which the city belongs. Finally, you must find the city you’re looking for. If it’s not under the appropriate country node, then it doesn’t exist. You also can traverse a tree in the opposite direction. You can start with a city and find its country. The country node is the city node’s parent fade. Notice that there is only one route from child nodes to their parent nodes, which means you can instantly locate the country or continent of a city. The same data shown are shown on a TreeView control. Only the nodes we’re interested in are expanded. The plus sign indicates that the corresponding node contains child nodes. To view them, click a plus sign to expand the node.
The tree structure is ideal for data with parent-child relationships (items that can be described llS ”belongs to” or “owns”). The continents-countries-cities data is a typical example. The folder structure on a hard disk is another typical example. Any .given folder is the child of another folder, or the root folder. If you need a method to traverse the folder structure of your hard disk quickly and conveniently, you must store the folders in a TreeView control. This is exactly what happens when you use the Windows Explorer to navigate your hard disk. Of course.there are other ways to navigate your hard disk (you can do the same with a File Open dialog box), but the TreeView control helps you visualize the structure of the entire disk: With the File Open dialog box, you can only view one ‘segment of the disk, namely, the path to the current folder.
Many programs are actually based on tree structures. Computerized board games use a tree structure to store all possible positions. Every time the computer has to make a move, it locates the board’s status on the tree and selects the “best” next move. For ,instance, in tic-tac-toe, the tree structure’ that represents the moves in the game has nine nodes on the first level, which correspond to all the possible positions for the first token on the board (the X or 0 mark). Under each possible initial position, there are eight nodes, which correspond to all the possible positions of the second token on the board (one.of the nine positions is already taken), On the second level, there are 9*8,or 72 nodes. On the third level, there are seven nodes under which node that correspond to all the possible positions of the third token, a total of 72*7, or 504 nodes on this level, and so on. In each node, you can store a value that indicates whether the corresponding move is good or bad. When the computer has to make a move, it traverses the tree to locate the current status of the board, and then it makes a good move.
Of course, tic-tac-toe is a very simple game. In principle, you could design a less playing game using a tree. This tree, however, would grow so large so quickly tl, It it couldn’t be stored in any reasonable amount of memory. Moreover, scanning the nodes of this enormous tree would be a slow process. If you also consider that chess moves aren’t good or bad (there. are better and not so good moves), and you must look ahead many moves to decide which move is the best for the current status of the board, you’ll realize that this ad-hoc approach is totally impractical. Practically speaking, such a program requires either infinite resources or infinite time. That’s why the chess-playing algorithms use heuristic approaches which store every recorded chess game arid consult this database to pick the best next move.
Maintaining a tree structure is a fundamental operation in software design; computer science students spend a good deal of their studies implementing tree structures. Even the efficient implementation of a tree structure is a research subject. Fortunately, with VisualBasic you don’t have to implement tree structures on your own. The TreeView control is a mechanism for storing hierarchically structured data packaged as an ActiveX control. The TreeView control hides (or encapsulates in object-oriented termirology) the details of the implementation and allows you to set up tree structures with a few lines of code. In short, all the gain without the pain. You may find this too good to be true, but if you’ve ever had to implement tree structures, you’ll appreciate the simplicity of the TreeView control.
Programming the TreeView control is not as simple as programming other controls, but keep in mind that the TreeView control implements a complicated data structure. It’s far simpler to program the TreeView control than to implement tree structures from scratch. There’s not much you can do about efficiency, and unless you’re developing highly specialized applications that rely on tree structures, the TreeView control is your best bet.
The ListView control implements a simpler structure, known as a list. A list’s !!ems aren’t structured in a hierarchy. They are all on the same level and can be traversed serially, one after the other. You can also think of the list as an array, but the list offers more features. A list item can have sub items and can be sorted in many
ways. For example, you can set up a list of customer names (the list’s items) and assign a number of sub items to each name, like an address, a phone number, and so on. Or, you can set up a list of files with their attributes as subitems. It shows a Windows folder mapped on a ListView control. Each file is an item and its attributes are the subitems. As you already know, you can sort this list by filename, size, file type, and so on. All you have to do is click the header c.l the corresponding column. You can also display the list of files in dfferent views: as icons, as a list of filenames only, or as a report. All this functionality is built into the ListView control, and all you have to do is populate the control and set various properties to change the sort order or the view.
The ListView control is a glorified ListBox control. If all you need is a control to store sorted strings, use a ListBox control. If you want more features, like storing multiple items per row, sorting them in different ways, or locating them based on any subitem’s value, then you must consider the ListView control. It’s simpler to program than the TreeView control, but still more involved than the simple List- Box control.
To program the TreeView and ListView controls, you must understand the concept of collections. You can’t simply add items to these controls with the AddItem method as you’d do with the ListBox control. Each level of nodes in the TreeView control is a collection. Each item in this collection represents a node, which may
have child nodes. Each node’s child nodes form another collection. Each item in this collection is a Node object, which in turn may have its own child Form, which is represented by another collection, and so on. We’ll discuss these techniques in detail, but there’s something else I would like to mention briefly and get out of the way as early as possible.
The Treeview and ListView controls are commonly used along with the Image- List control. The ImageList control is a very simple control {or storing images, so they can be retrieved quickly arid used at runtime. Before we get into the details of the TreeView and ListView controls, a quick overview of the ImageList control is in order.
The ImageList Control
The ImageList control is a .really simple control that stores a number of images used by other controls at runtime. For example, a TreeView control may use a number of icons to identify its nodes. The simplest and quickest method of setting up the Tree- View is to create an ImageList with icons to use, The ImageList control maintains a series of bitmaps in its memory that the TreeView control can access very quickly at runtime. Keep in mind that the ImageListControl can’t be used on its own and remains invisible at runtime,
The Images stored in the ImageList control can be used for any purpose by your application, but in this book, we’ll use them in conjunction with the TreeView and ListView controls, which use them to identify their nodes and list items, respectively. So, before we start the discussion of the TreeView and ListView controls, let’s look at how to store images in an ImageList control and how to use this control in your code.
To use the ImageList control in a project, add the Windows Common Controls-2 component. To load images to an ImageList control, right-click it and select Properties. On the first tab of the control’s property pages, specify the size of the images, which can have one of the following values: 16 x 16, 32 x 32, 48 x48, or Custom. If you check the Custom checkbox you must supply the desired dimensions, which will be the same for all images.
On the second tab, shown, you can add as many image as you need to the control. To add a new image, click the Insert Picture button and you’ll be asked to select an image with a standard File Open dialog box. You can add all types of images recognized by Visual Basic (BMP, GIF, JPEG files), as well as icons (lCO files) and cursors (CUR files).’
Each image stored in the ImageList control can be’identified by an Index value or a key. The Index value is determined by the position of the image in the control and the Key value must be supplied on the Images tab. You can also set a tag for each image.
The other method of adding images to an ImageList control is to call the Add . method of the ListImages collection, which contains all the images stored in the control. To add an image at runtime, you must make sure that the image file exists on the target computer and then call the Add method as follows:
lmageListl.Listlmages.Add index, key, picture
The arguments of the Add method are the same properties you can set on the control’s property pages at design time. To specify additional properties such as the Tag property, use the following alternate syntax of the Add method:
Set” thisImage – lmageListl. Listlmages.. Add(index, key, ‘picture)
The variable thisJmage is a ListImage object and it’s declared as:
Dim thislmage As Listlmage
The Add method returns a ListImage object representing the newly added image. To set the image’s Tag property, use the statement:
Thislmage.Tag – “Weather Element”
ListImages is a collection of Picture objects, not the file where the pictures are stored. Therefore, the last argument of the Add method must the Picture property of another control (a PictureBox control, for example). To add an image from a file, you must use the LoadPicture function (the Same function you’d use to load “an image on a PictureBox control). To load the image stored in the “Sun.bmp” file in the application’s folder, use this statement:
Iinagetistl. Listlmages.Add 0, “SUN”, LoadPicture(App. Path &. “Sun .bmp”
To use one of the pictures stored in the ImageList control, extract the corresponding item’s Picture property and assign it to the Picture property of another control:
Picturel.Picture – lmageListl.listimages(O).Picture
You can also access the properties of the Picture object, such as its dimensions, with the following statements:
·ImageListl.Listlmages(O).Picture.Width
lmageListl.Listlmages(O).Picture.Height
As you’ll see in the following sections, the simplest method of accessing the pictures of the ImageList control is to assign the control to the ImageList property of a control. Not all controls have an -ImageList property, but the two controls , we’Il explore in the following section do.