Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(ebook) Visual Studio .NET Mastering Visual Basic.pdf
Скачиваний:
120
Добавлен:
17.08.2013
Размер:
15.38 Mб
Скачать

766 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

CountryNode = CountryNode.NextNode

Next

ContinentNode = ContinentNode.NextNode

Next

End Sub

When the ContinentNode.Next method is called, it returns the next node in the Continents level. Then the ContinentNode.Nodes(0) method is called, and it returns the first node in the Countries level. As you can guess, the code of the List Cities button uses the same two nested lists as the previous listing and an added inner loop, which scans the cities of each country.

The code behind these Command buttons requires some knowledge of the information stored in the tree. It will work with trees that have two or three levels of nodes such as the Globe tree, but what if the tree’s depth is allowed to grow to a dozen levels? A tree that represents the structure of a folder on your hard disk, for example, may easily contain a dozen nested folders. Obviously, to scan the nodes of this tree you can’t put together unlimited nested loops. The next section describes a technique for scanning any tree, regardless of how many levels it contains. The code in the following section uses recursion, and if you’re not familiar with recursive programming, then you should first read Chapter 18.

Scanning the TreeView Control

The items of a TreeView control can all be accessed through the Nodes collection. You have seen how to scan the entire tree of the TreeView control with a For Each…Next loop. This technique, however, requires that you know the structure of the tree, and you must write as many nested loops as there are nested levels of nodes. It works with simple trees, but it’s quite inefficient when it comes to mapping a file system to a TreeView control.

VB.NET at Work: The TreeViewScan Project

To demonstrate the process of scanning a TreeView control, I have included the TreeViewScan project on the CD. The application’s form is shown in Figure 16.10. The Form contains a TreeView control on the left, which is populated with the same data as the Globe’s TreeView control, and a ListBox control on the right, where the tree’s nodes are listed. Child nodes on the ListBox control are indented according to the level to which they belong.

Figure 16.10

The TreeViewScan application demonstrates how to scan the nodes of a TreeView control recursively.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 767

Scanning the child nodes in a tree calls for a recursive procedure, or a procedure that calls itself. Think of a tree structure that contains all the files and folders on your C: drive. If this structure contained no subfolders, you’d need to set up a loop to scan each folder, one after the other. Since most folders contain subfolders, the process must be interrupted at each folder to scan the subfolders of the current folder. The process of scanning a drive recursively was described in detail in Chapter 13.

Recursive Scanning

To start the scanning of the TreeView1 control, start at the top node of the control with the statement

Protected Sub bttnScanTree_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

ScanNode(GlobeTree.Nodes(0))

End Sub

This is the code behind the Scan Tree button, and it doesn’t get any simpler. It calls the ScanNode() subroutine to scan the child nodes of a specific node, which is passed to the subroutine as an argument. GlobeTree.Nodes(0) is the root node. By passing the root node to the ScanNode() subroutine, we’re in effect asking it to scan the entire tree.

This example assumes that the TreeView control contains a single root node and that all other nodes are under the root node. If your control contains multiple root nodes, then you must set up a small loop and call the ScanNode() subroutine once for each root node:

For Each node In GlobeTree.Nodes

ScanNode(node)

Next

Let’s look now at the ScanNode() subroutine, shown in Listing 16.11.

Listing 16.11: Scanning a Tree Recursively

Sub ScanNode(ByVal node As TreeNode)

Dim thisNode As TreeNode

Static IndentLevel As Integer

Application.DoEvents()

ListBox1.Items.Add(Space(IndentLevel) & node.Text)

If node.Nodes.Count > 0 Then

IndentLevel += 5

For Each thisNode In node.Nodes

ScanNode(thisNode)

Next

IndentLevel -= 5

End If

End Sub

This subroutine is deceptively simple. First, it adds the caption of the current node to the ListBox1 control. If this node (represented by the Node variable) contains child nodes, the code must scan them all. The Node.Nodes.Count method returns the number of nodes under the current node. If this value

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com