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

754 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

Germany. PrevNode and NextNode allow you to iterate through the nodes of the current segment: they return the next and previous nodes on the current segment of the tree (the sibling nodes, as they’re called). See the section “Enumerating the Nodes Collection,” later in this chapter, for an example.

Assigning Images to Nodes

To display an image in front of a node’s caption, you must first initialize an ImageList control and populate it with all the images you plan to use with the TreeView control. The Node object exposes two image-related properties: ImageIndex and SelectedImageIndex. Both properties are the indices of an image in an ImageList control, which contains the images to be used with the control. To connect the ImageList control to the TreeView object (as well as the ListView object, which is discussed later in the chapter), you must assign the name of the ImageList control to the ImageList property of the TreeView control. Then you can specify images by their index in the ImageList control.

The ImageIndex property is the index of the image you want to display in front of the node’s caption. The SelectedImageIndex is the index of the image you want to display when the node is selected (expanded). Windows Explorer, for example, uses the icon of a closed folder for all collapsed nodes and the icon of an open folder for all expanded nodes. If you don’t specify a value for the SelectedImageIndex property, then the image specified with the ImageIndex property will be displayed. If you haven’t specified a value for this property either, then no image will be displayed for this node.

VB.NET at Work: The TreeViewDemo Project

It’s time to demonstrate the members discussed so far with an example. The project you’ll build in this section is the TreeViewDemo project, and you can find it in this chapter’s folder on the CD. The project’s main form is shown in Figure 16.8.

Figure 16.8

The TreeViewDemo project

The Add Categories button adds the three top-level nodes to the TreeView control with the statements shown in Listing 16.1. These are the control’s root nodes. The other two buttons add items under the root nodes.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 755

Listing 16.1: The Add Categories Button

Protected Sub AddCategories_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

TreeView1.Nodes.Add(“Shapes”)

TreeView1.Nodes.Add(“Solids”)

TreeView1.Nodes.Add(“Colors”)

End Sub

When these statements are executed, three root nodes will be added to the list. After clicking the Add Categories button, your TreeView control looks like the one shown at the left.

To add a few nodes under the node Colors, you must retrieve the Colors Nodes collection and add child nodes to this collection, as shown in Listing 16.2.

Listing 16.2: The Add Colors Button

Protected Sub AddColors_Click(ByVal sender As Object, _ ByVal e As System.EventArgs)

Dim cnode As TreeNode cnode = TreeView1.Nodes(2) cnode.Nodes.Add(“Pink”) cnode.Nodes.Add(“Maroon”) cnode.Nodes.Add(“Teal”)

End Sub

When these statements are executed, three nodes will be added under the Colors node, but the Colors node won’t be expanded. Therefore, its child nodes won’t be visible. To see its child nodes, you must double-click the Colors node to expand it (or click the plus sign in front of it, if there is one). The same TreeView control with its Colors node expanded is shown to the left. Alternatively, you can add a statement that calls the Expand method of the cnode object, after adding the color nodes to the control:

cnode.Expand()

Run the project, click the first button (Add Categories) and then the second button (Add Colors). If you click the Add Colors button first, you’ll get a NullReferenceException, indicating that node can’t be inserted unless its parent node exists already. You can add a few statements in the TreeViewDemo project’s code to disable the buttons that generate similar runtime errors.

To add child nodes under the Shapes node, use the statements shown in Listing 16.3. This is the Shapes button’s Click event handler.

Listing 16.3: The Add Shapes Button

Protected Sub AddShapes_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

Dim snode As TreeNode

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

756 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

snode = treeview1.Nodes(0) snode.Nodes.Add(“Square”) snode.Nodes.Add(“Triangle”) snode.Nodes.Add(“Circle”)

End Sub

Add a third Command button on the form, name it Add Shapes, and insert these lines in its Click event handler. If you run the project and click the three buttons in the order in which they appear on the Form, the TreeView control will be populated with Colors and Shapes. If you double-click the items Colors and Shapes, the TreeView control’s nodes will be expanded.

Notice that the code knows the order of the root node to which it’s adding child nodes. Your application should know the node under which it must add new child nodes. You could scan the entire tree to locate an item, but then again the node names are not unique, not even within a Nodes collection.

This approach doesn’t work with a sorted tree. If your TreeView control is sorted, you must create a hierarchy of nodes explicitly, with the following statements:

snode = TreeView1.Nodes.Add(“Shapes”) snode.Add(“Square”) snode.Add(“Circle”) snode.Add(“Triangle”)

These statements will work regardless of the control’s Sorted property setting. The three shapes will be added under the Shapes nodes, and their order will be determined automatically. Of course, you can always populate the control in any way you like and then turn on the Sorted property.

Let’s revise the code we’ve written so far to display all the nodes under a header called Items. In other words, we’ll add a new node that will act as the root node for existing nodes. It’s not a common operation, but it’s an interesting example of how to manipulate the nodes of a TreeView control.

First, we must add the root, a node that will contain all other nodes as children. Before we do so, however, we must copy into local variables all the first-level nodes. We’ll use these variables to add the current root nodes under the new (and single) root node. There are three root nodes currently in our control, so we need three local variables. The three variables are of the TreeNode type, and they’re set to the root nodes of the original tree. Then we must clear the entire tree, add the new root node (the Items node), and finally add all the copied nodes under the new root. The code behind the Move Tree button is shown in Listing 16.4.

Listing 16.4: Moving an Entire Tree

Protected Sub MoveTree_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles bttnMoveTree.Click Dim colorNode, shapeNode, solidNode As TreeNode

colorNode = TreeView1.Nodes(0) shapeNode = TreeView1.Nodes(1) solidNode = TreeView1.Nodes(2) TreeView1.Nodes.Clear()

TreeView1.Nodes.Add(“Items”)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 757

TreeView1.Nodes(0).Nodes.Add(colorNode)

TreeView1.Nodes(0).Nodes.Add(shapeNode)

TreeView1.Nodes(0).Nodes.Add(solidNode)

End Sub

You can revise this code so that it uses an array of Node objects to store all the root nodes instead of their count. For a routine that will work with any tree, you must assume that the number of nodes is unknown, so the ArrayList would be a better choice. The following loop stores all the root nodes of the TreeView1 control to the TVList ArrayList:

Dim node As TreeNode

For Each node in TreeView1.Nodes

TVList.Add(node)

Next

Likewise, the following loop extracts the root nodes from the TVList object:

Dim node As TreeNode Dim itm As Object TreeView1.Nodes.Clear For Each itm In TVList

node = CType(itm, TreeNode) TreeView1.Nodes.Add(node)

Next

Enumerating the Nodes Collection

Each group of child nodes forms a Nodes collection, which exposes several methods. As you have seen in the last example, a Node object may include an entire tree under it. When we move a node, it takes with it the entire Nodes collection under it. The FirstNode property returns the first node in the collection, the LastNode property returns the last node in the collection, and the NextNode and PrevNode properties return the next and previous nodes in the collection, respectively. You can scan all the nodes in the CurrentNode collection with a loop, which starts with the first node and then moves to the next node with the help of the FirstNode and NextNode properties. The following loop prints the names of all continents on the GlobeTree control:

Dim node As TreeNode

node = GlobeTree.Nodes(0).Nodes(0).FirstNode While node <> Nothing

Console.WriteLine(node.text) node = node.NextNode

End While

The last property demonstrated by the TreeViewDemo project is the Sorted property, which sorts the child nodes of the node to which it’s applied. When you set the Sorted property of a node to True, every child node you attach to it will be inserted automatically in alphabetical order.

Note If you reset the Sorted property to False and add another node, it will be appended to the end of the existing (and sorted) nodes. This is how new child nodes are added to a parent node when its Sorted property is False.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

758 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

VB.NET at Work: The Globe Project

The Globe project, which you can find in this chapter’s folder on the CD, demonstrates many of the techniques we’ve discussed so far. It’s not the simplest example of a TreeView control, and its code is lengthy, but it will help you understand how to manipulate nodes at runtime. As you know by now, TreeView is not a simple control, so before ending this section I would like to show you a fairly advanced example that you can use as a starting point for your own custom applications. You’ll also see how to save the nodes of a TreeView control to a disk file and retrieve them later.

Figure 16.9

The Globe project

The Globe project consists of a single form, which is shown in Figure 16.9. The TreeView control at the left contains a tree structure with continents, countries, and cities, with a rather obvious structure. Each city belongs to a country, and each country belongs to a continent. The control is initially populated with the continents, which were added at design time. The countries and cities are added from within the form’s Load event handler. The continents were added at design time, but as you will see, there’s no particular reason not to add them to the control at runtime. It would have been actually simpler to add all the nodes at runtime, but I’ve decided to add a few nodes at design time just for demonstration purposes.

When a node is selected in the TreeView control, its text is displayed on the TextBox controls at the bottom of the form. When a continent name is selected, the continent’s name appears in the first TextBox, and the other two TextBoxes are empty. When a country is selected, its name appears in the second TextBox, and its continent appears in the first TextBox. Finally, when a city is selected, it appears in the third TextBox, along with its country and continent in the other two TextBoxes.

You can also use the TextBox controls to add new nodes. To add a new continent, just supply the name of the continent in the first TextBox and leave the other two empty. To add a new country, supply its name in the second TextBox and the name of the continent it belongs to in the first one. Finally, to add a city, supply a continent, country, and city name in the three TextBoxes.

Run the Globe application and expand the continents and countries to see the tree structure of the data stored in the control. Add new nodes to the control, and enumerate these nodes by clicking

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 759

the appropriate button on the right-hand side of the form. These buttons list the nodes at a given level (continents, countries, and cities). When you add new nodes, the code places them in their proper place in the list. If you specify a new city and a new country under an existing continent, then a new country node will be created under the specified continent, and a new city node will be inserted under the specified country.

Coding the Globe Project

Let’s take a look at the code of the Globe project. We’ll start by looking at the code that populates the TreeView control. The root node (GLOBE) and the continent names were added at design time through the TreeNode Editor. In many cases, it is convenient to add the first few nodes, or at least the root node, at design time.

After the continents are in place, the code adds the countries to each continent and the cities to each country. The code in the form’s Load event goes through all the continents already on the control and examines their Text property. Depending on the continent represented by the current node, it adds the corresponding countries and some city nodes under each country node.

If the current node is Africa, the first country to be added is Egypt. The Egypt node is added to the ContinentNode object. The new node is returned as a TreeNode object and is stored in the CountryNode object. Then the code uses this object to add nodes that correspond to cities under the Egypt node. The form’s Load event handler is quite lengthy, so I’m showing (Listing 16.5) only the code that adds the first country under each continent and the first city under each country.

Listing 16.5: Adding the Nodes of Africa

For Each ContinentNode In GlobeNode.Nodes

Select Case ContinentNode.Text

Case “Europe”

CountryNode = ContinentNode.Nodes.Add(“Germany”)

CountryNode.Nodes.Add(“Berlin”)

Case “Asia”

CountryNode = ContinentNode.Nodes.Add(“China”)

CountryNode.Nodes.Add(“Beijing”)

Case “Africa”

CountryNode = ContinentNode.Nodes.Add(“Egypt”)

CountryNode.Nodes.Add(“Cairo”)

CountryNode.Nodes.Add(“Alexandria”)

Case “Oceania”

CountryNode = ContinentNode.Nodes.Add(“Australia”)

CountryNode.Nodes.Add(“Sydney”)

Case “N. America”

CountryNode = ContinentNode.Nodes.Add(“USA”)

CountryNode.Nodes.Add(“New York”)

Case “S. America”

CountryNode = ContinentNode.Nodes.Add(“Argentina”)

End Select

Next

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

760 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

The remaining countries and their cities are added with similar statements, which you can examine if you open the Globe project. Notice that the GlobeTree control could have been populated entirely at design time, but this wouldn’t be much of a demonstration. Let’s move on to a few more interesting aspects of programming the TreeView control.

Retrieving the Selected Node

The selected node is given by the property SelectedNode. Once you can retrieve the selected node, you can also retrieve its parent node and the entire path to the root node. The parent node of the current control is TreeView1.SelectedNode.Parent. If this node has a parent, you can retrieve it by calling the Parent property of the previous expression (TreeView1.SelectedNode.Parent.Parent). Or you can use the FullPath property to retrieve the selected node’s full path. The FullPath property of the Rome node is

GLOBE\Europe\Italy\Rome

The slashes separate the segments of the node’s path. You can specify any other character for this purpose by setting the control’s PathSeparator property.

To remove the selected node from the tree, call the Remove method:

TreeView1.SelectedNode.Remove

If the selected node is a parent control for other nodes, the Remove method will take with it all the nodes under the selected one. You can also use the IsSelected property of the Node object to find out whether a specific node is selected or not. The IsSelected property returns a True/False value, depending on the status of the node. A similar property, the IsExpanded property, allows you to find out whether a specific node is expanded or not.

One of the operations you’ll want to perform with the TreeView control is to capture the selection of a node. The TreeView control fires the AfterSelect event, which notifies your application of the selection of another node. If you need to know which node was previously selected, you must use the BeforeSelect event. The second argument of both events has two properties, the Node and Action properties, which let you find out the node that fired the event and the action that caused it. The e.Node property is a TreeViewNode object that represents the selected node. Use it in your code as you would use any other node of the control. The e.Action property is a member of the TreeViewAction enumeration (ByKeyboard, ByMouse, Collapse, Expand, Unknown). Use this property to find out the action that caused the event. The actions of expanding and collapsing a tree branch fire their own events, which are the BeforeExpand/AfterExpand and the BeforeCollapse/ AfterCollapse events, respectively.

VB6 VB.NET

The VB6 version of the TreeView control recognized the NodeClick event, which was fired every time the user selected another node in the control. The NodeClick event has been replaced by the AfterSelect event.

The Globe project retrieves the selected node and extracts the parts of the node’s path. The individual components of the path are displayed in the three TextBox controls at the bottom of the form. Listing 16.6 shows the event handler for the TreeView control’s AfterSelect event.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 761

Listing 16.6: Processing the Selected Node

Private Sub GlobeTree_AfterSelect(ByVal sender As Object, _

ByVal e As System.Windows.Forms.TreeViewEventArgs) _ Handles GlobeTree.AfterSelect

If GlobeTree.SelectedNode Is Nothing Then Exit Sub Dim components() As String

txtContinent.Text = “” txtCountry.Text = “” txtCity.Text = “”

components = Split(GlobeTree.SelectedNode.FullPath.ToString, _ GlobeTree.PathSeparator)

Console.WriteLine(GlobeTree.SelectedNode.FullPath.ToString)

If components.Length > 1 Then txtContinent.Text = components(1) If components.Length > 2 Then txtCountry.Text = components(2) If components.Length > 3 Then txtCity.Text = components(3)

End Sub

The Split() function of VB extracts the parts of a string that are delimited by a special character. For the case of the TreeView control, this special character is given by the property PathSeparator, and the default value of this property is the character “\”. If any of the captions contain this character, you should change the default to a different character by setting the PathSeparator property to something else.

The code behind the Delete Current Node and Expand Current Node buttons is simple. To delete a node, call the selected node’s Remove method:

GlobeTree.SelectedNode.Remove

The other button expands the current node by calling the Expand method of the selected node:

GlobeTree.SelectedNode.Expand

The TreeNode object exposes the ExpandAll method, too, which expands not only the specified node but all the Nodes collections under it (its child nodes).

Processing Multiple Selected Nodes

The GlobeTree TreeView control has its CheckBoxes property set to True so that users can select multiple nodes. I’ve added this feature to demonstrate how you can retrieve the selected nodes and process them.

As you will notice by experimenting with the TreeView control, you can check a node that has subordinate nodes, but these nodes will not be affected. They will remain unchecked (or checked, if you have already checked them). In most cases, however, when we check a parent node, we actually intend to check all the nodes under it. When you check a country, for example, you’re in effect selecting not only the country but all the cities under it. The code of the Process Selected Nodes button assumes that when a parent node is checked, it must also check all the nodes under it.

Let’s look at the code that iterates through the control’s nodes and isolates the selected ones. It doesn’t really process them, it simply prints them on the ListBox control. However, you can call a

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

762 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

function to process the selected nodes in any way you like. The code behind the Process Selected Nodes button starts with the continents. It creates a TreeNodeCollection with all the continents and then goes through the collection with a For Each…Next loop. At each step, it creates a new TreeNodeCollection, which contains all the subordinate nodes (the countries under the selected continent) and goes through the new collection. This loop is also interrupted at each step to retrieve the cities in the current country and process them with another loop. The following pseudo-code listing outlines the code:

Set up the Continents Collection

For Each continent In Continents

If continent is selected Then process it

Set up the Countries Collection

For Each country In Countries

If country is selected Then process it

Set up the Cities Collection

For Each city In Cities

If city is selected Then process it

Next

Next

Next

The code behind the Process Selected Nodes button implements the pseudo-code shown above and is shown in Listing 16.7.

Listing 16.7: Processing All Selected Nodes

Protected Sub bttnProcessSelected_Click(ByVal sender As Object, _

ByVal e As System.EventArgs)

Dim continent, country, city As TreeNode

Dim Continents, Countries, Cities As TreeNodeCollection

ListBox1.Items.Clear()

Continents = GlobeTree.Nodes(0).Nodes

For Each continent In Continents

If continent.Checked Then ListBox1.Items.Add(continent.FullPath)

Countries = continent.Nodes

For Each country In Countries

If country.Checked Or country.Parent.Checked Then _

ListBox1.Items.Add(“

“ & country.FullPath)

Cities = country.Nodes

 

 

For Each city In Cities

 

 

If city.Checked Or city.Parent.Checked Or _

city.Parent.Parent.Checked Then _

 

ListBox1.Items.Add(“

“ & city.FullPath)

Next

 

 

Next

Next

End Sub

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 763

The code examines the Checked property of the current node, as well as the Checked property of its parent node. If either one is True, then the node is considered selected. You should try to add the appropriate code to select all subordinate nodes of a parent node when the parent node is selected (whether you deselect the subordinate nodes when the parent node is deselected is entirely up to you and the type of application you’re developing). The Nodes collection exposes the GetEnumerator method, which should be very familiar to you by now. You can revise the last listing so that it uses an enumerator in the place of each For Each…Next loop.

Adding New Nodes

The Add Node button lets the user add new nodes to the tree at runtime. The number and type of the node(s) added depend on the contents of the TextBox controls:

If only the first TextBox control contains text, then a new continent will be added.

If the first two TextBox controls contain text, then:

If a continent exists, a new country node is added under the specified continent.

If a continent doesn’t exist, a new continent node is added, and then a new country node is added under the continent’s node.

If all three TextBox controls contain text, the program adds a continent node (if needed), then a country node under the continent node (if needed), and finally, a city node under the country node.

Obviously, you can omit a city, or a city and country, but you can’t omit a continent name. Likewise, you can’t specify a city without a country or a country without a continent. The code will prompt you accordingly when it detects a condition that prevents it from adding the new node for any reason. If the node exists already, then the program selects the existing node and doesn’t issue any warnings. The Add Node button’s code is shown in Listing 16.8.

Listing 16.8: Adding Nodes at Runtime

Private Sub bttnAddNode_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles bttnAddNode.Click Dim nd As TreeNode

Dim Continents As TreeNode

If txtContinent.Text.Trim <> “” Then Continents = GlobeTree.Nodes(0)

Dim ContinentFound, CountryFound, CityFound As Boolean Dim ContinentNode, CountryNode, CityNode As TreeNode For Each nd In Continents.Nodes

If nd.Text.ToUpper = txtContinent.Text.ToUpper Then ContinentFound = True

Exit For End If

Next

If Not ContinentFound Then

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

764 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS

nd = Continents.Nodes.Add(txtContinent.Text) End If

ContinentNode = nd

If txtCountry.Text.Trim <> “” Then Dim Countries As TreeNode Countries = ContinentNode

If Not Countries Is Nothing Then For Each nd In Countries.Nodes

If nd.Text.ToUpper = txtCountry.Text.ToUpper Then CountryFound = True

Exit For End If

Next End If

If Not CountryFound Then

nd = ContinentNode.Nodes.Add(txtCountry.Text) End If

CountryNode = nd

If txtCity.Text.Trim <> “” Then Dim Cities As TreeNode Cities = CountryNode

If Not Cities Is Nothing Then For Each nd In Cities.Nodes

If nd.Text.ToUpper = txtCity.Text.ToUpper Then CityFound = True

Exit For End If

Next End If

If Not CityFound Then

nd = CountryNode.Nodes.Add(txtCity.Text) End If

CityNode = nd End If

End If End If

End Sub

The listing is quite lengthy, but it’s not hard to follow. First, it attempts to find a continent that matches the name in the first TextBox. If it succeeds, it need not add a new continent node. If not, then a new continent node must be added. To avoid simple data-entry errors, the code converts the continent names to uppercase before comparing them to the uppercase of each node’s name. The same happens with the countries and the cities. As a result, each node’s pathname is unique. You can’t have the same city name under the same country more than once. It is possible, however, to add the same city name to two different countries. The example is not quite realistic, as there are common city names in every country.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

THE TREEVIEW CONTROL 765

Listing Continents/Countries/Cities

The three buttons List Continents, List Countries, and List Cities populate the ListBox control with the names of the continents, countries, and cities, respectively. The code is straightforward and is based on the techniques discussed in previous sections. To print the names of the continents, it iterates through the children of the GLOBE node. Listing 16.9 shows the complete code of the List Continents button.

Listing 16.9: Retrieving the Continent Names

Private Sub bttnListContinents_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles bttnListContinents.Click Dim Nd As TreeNode, continentNode As TreeNode

Dim continent As Integer, continents As Integer ListBox1.Items.Clear()

Nd = GlobeTree.Nodes(0) continents = Nd.Nodes.Count continentNode = Nd.Nodes(0) For continent = 1 To continents

ListBox1.Items.Add(continentNode.Text) continentNode = continentNode.NextNode

Next End Sub

The code behind the List Countries names is equally straightforward, although longer. It must scan each continent, and within each continent, it must scan in a similar fashion the continent’s child nodes. To do this, you must set up two nested loops, the outer one to scan the continents and the inner one to scan the countries. The complete code for the List Countries button is shown in Listing 16.10. Notice that in this example, I’m using For…Next loops to iterate through the current level’s nodes, and I also use the NextNode method to retrieve the next node in the sequence.

Listing 16.10: Retrieving the Country Names

Private Sub bttnListCountries_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles bttnListCountries.Click Dim Nd, CountryNode, ContinentNode As TreeNode

Dim continent, continents, country, countries As Integer ListBox1.Items.Clear()

Nd = GlobeTree.Nodes.Item(0) continents = Nd.Nodes.Count ContinentNode = Nd.Nodes(0)

For continent = 1 To continents countries = ContinentNode.Nodes.Count CountryNode = ContinentNode.Nodes(0) For country = 1 To countries

ListBox1.Items.Add(CountryNode.Text)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com