Click to See Complete Forum and Search --> : TreeView


WOTR
June 21st, 2001, 08:37 AM
Can anybody send me any sample code on this?

Cimperiali
June 21st, 2001, 08:42 AM
http://codeguru.earthweb.com/cgi-bin/bbs/wt/showpost.pl?Board=vb&Number=49477&page=0&view=collapsed&sb=

Special thanks to Lothar "the Great" Haensler, Tom Archer, Chris Eastwood, Bruno Paris and all the other wonderful people who made and make Codeguru a great place. Come back soon, you Gurus.

Iouri
June 21st, 2001, 08:44 AM
here is a sample of using a treeview

Private Sub Command1_Click()
'======================
List1.Clear
ListChildren TreeView1, List1
End Sub

Private Sub Form_Load()
'======================
TreeView1.LineStyle = tvwRootLines

Dim nodX As Node

'Add the roots
Set nodX = TreeView1.Nodes.Add(, , "r", "The First Root")
Set nodX = TreeView1.Nodes.Add(, , "r2", "The Second Root")
'Add the children of the first root
Set nodX = TreeView1.Nodes.Add("r", tvwChild, "1child1", "Child 1")
Set nodX = TreeView1.Nodes.Add("r", tvwChild, "1child2", "Child 2")
Set nodX = TreeView1.Nodes.Add("r", tvwChild, "1child3", "Child 3")
'Add the children of the second root
Set nodX = TreeView1.Nodes.Add("r2", tvwChild, "2child1", "Child 1")
Set nodX = TreeView1.Nodes.Add("r2", tvwChild, "2child2", "Child 2")

End Sub

Private Sub Timer1_Timer()
'======================
On Error Resume Next
Label2.Caption = "Root Name: " & GetRootName(TreeView1)
Label3.Caption = "RootIndex: " & GetRootIndex(TreeView1)
Label4.Caption = "Root Children: " & GetRootChildren(TreeView1)
Label5.Caption = "Child Name: " & GetChildName(TreeView1)
Label6.Caption = "Child Index: " & GetChildIndex(TreeView1)
End Sub

Private Function GetRootName(tvw As TreeView)
'======================
On Error GoTo RootIsSelected
GetRootName = tvw.SelectedItem.Parent.Text
Exit Function
RootIsSelected:
GetRootName = tvw.SelectedItem.Text
End Function

Private Function GetRootIndex(tvw As TreeView)
'======================
On Error GoTo RootIsSelected
GetRootIndex = tvw.SelectedItem.Parent.Index
Exit Function
RootIsSelected:
GetRootIndex = tvw.SelectedItem.Index
End Function

Private Function GetRootChildren(tvw As TreeView)
'======================
On Error Resume Next
GetRootChildren = tvw.Nodes(GetRootIndex(tvw)).Children
End Function

Private Function GetChildName(tvw As TreeView)
'======================
GetChildName = tvw.SelectedItem.Text
End Function

Private Function GetChildIndex(tvw As TreeView)
'======================
GetChildIndex = tvw.SelectedItem.Index
End Function

Private Function ListChildren(tvw As TreeView, lst As ListBox)
'======================
Dim StrToAdd As String
Dim StartIndex As Integer

StartIndex = tvw.Nodes(GetRootIndex(tvw)).Child.Index

For i = StartIndex To GetRootChildren(tvw) + StartIndex - 1
StrToAdd = tvw.Nodes(i).Text
lst.AddItem StrToAdd
Next i
End Function


Iouri Boutchkine
iouri@hotsheet.com

Cimperiali
June 21st, 2001, 08:51 AM
From Msdn:
Using the TreeView Control


The TreeView control is designed to display data that is hierarchical in nature, such as organization trees, the entries in an index, the files and directories on a disk.

Possible Uses
To create an organization tree that can be manipulated by the user.


To create a tree that shows at least two or more levels of a database.
Setting Node Object Properties
A "tree" is comprised of cascading branches of "nodes," and each node typically consists of an image (set with the Image property) and a label (set with the Text property). Images for the nodes are supplied by an ImageList control associated with the TreeView control. For more information on using the ImageList control with other controls, see "Using the ImageList control."

A node can be expanded or collapsed, depending on whether or not the node has child nodes — nodes which descend from it. At the topmost level are "root" nodes, and each root node can have any number of child nodes. The total number of nodes is not limited (except by machine constraints). Figure 2.41 shows a tree with two root nodes; "Root 1" has three child nodes, and "Child 3" has a child node itself. "Root 2" has child nodes, as indicated by the "+" sign, but is unexpanded.

Each node in a tree is actually a programmable Node object, which belongs to the Nodes collection. As in other collections, each member of the collection has a unique Index and Key property which allows you to access the properties of the node. For example, the code below uses the Index of a particular node ("7") to set the Image and Text properties:

tvwMyTree.Nodes(7).Image = "closed"
tvwMyTree.Nodes(7).Text = "IEEE"

However, if a unique key, for example "7 ID" had been assigned to the node, the same code could be written as follows:

tvwMyTree.Nodes("7 ID").Image = "closed"
tvwMyTree.Nodes("7 ID").Text = "IEEE"

Node Relationships and References to Relative Nodes
Each node can be either a child or a parent, depending on its relationship to other nodes. The Node object features several properties which return various kinds of information about children or parent nodes. For example, the following code uses the Children property to return the number of children — if any — a node has:

MsgBox tvwMyTree.Nodes(10).Children

However, some of the properties do not return information, as the Children property does, but instead return a reference to another node object. For example, the Parent property returns a reference to the parent of any particular node (as long as the node is not a root node). With this reference, you can manipulate the parent node by invoking any methods, or setting properties, that apply to Node objects. For example, the code below returns the Text and Index properties of a parent node:

MsgBox tvwMyTree.Nodes(10).Parent.Text
MsgBox tvwMyTree.Nodes(10).Parent.Index

Tip Use the Set statement with an object variable of type Node to manipulate references to other Node objects. For example, the code below sets a Node object variable to the reference returned by the Parent property. The code then uses the object variable to return properties of the relative node:

Dim tempNode As Node ' Declare object variable.
' Set object variable to returned reference.
Set tempNode = tvwMyTree.Nodes(10).Parent
MsgBox tempNode.Text ' Returns parent's Text.
MsgBox tempNode.Index ' Returns parent's Index.

Adding Node Objects to the Nodes Collection
To add a Node to the tree, use the Add method (Nodes collection). This method includes two arguments, relative and relationship, which can determine where the node will be added. The first argument relative names a node; the second argument relationship specifies the relationship between the new node and the node named in relative.

For example, the following code adds a node named "11 node" as a child of another node named "7 node." The intrinsic constant tvwChild specifies that the new node is a child of the node named in the previous argument. The third argument assigns the Key property to the new node.

tvwMyTree.Nodes.Add "7 node", tvwChild, "11 node"

Other possible relationships include:

Constant Value Description
tvwLast 1 The Node is placed after all other nodes at the same level of the node named in relative.
tvwNext 2 The Node is placed after the node named in relative.
tvwPrevious 3 The Node is placed before the node named in relative.
tvwChild 4 The Node becomes a child node of the node named in relative.


For example, suppose there were three existing nodes, and you wished to place a fourth node between the second and the third nodes, the code would be:

' Assuming the second node's Key value is "2 node".
tvwMyTree.Nodes.Add "2 node", tvwNext

Other arguments of the Add method are key, text, and image. Using these arguments, you can assign the Key, Text, and Image properties as the Node object is created.

For More Information For more information about the Nodes collection's Add method See "Add Method" by typing "Add Method" in the Index search and clicking "Add Method (Nodes Collection)."

A second way of adding nodes is to declare an object variable of type Node, and then use the Set statement with the Add method. The Set statement sets the object variable to the new node. You can then use the object variable to set the node's properties, as shown below:

Dim nodX As Node
Set nodX = tvwMyTree.Nodes.Add("10 node", tvwChild)
nodX.Key = "11 node"
nodX.Text = "IEEE"
nodX.Image = "closed"

Tip Using the Set statement with the Add method makes reading and debugging your code easier. However, using the Add method and its arguments to add nodes creates faster code.

'-----------------------------------------------------------------------------------------------
TreeView Control Scenario: Bind the TreeView to the Biblio.mdb Database


Sample Application: DataTree.vbp
The code examples in this chapter are taken from the DataTree.vbp sample application which is listed in the Samples directory.

It is possible to bind the data from a database to a TreeView control. The following example binds a TreeView control to the Biblio database which is found on the Visual Basic CD. The scenario uses the Publishers table as the first level of tree nodes. If a publisher has one or more book titles, those titles are added to the tree as child nodes of the specific publisher.

Figure 2.42 Data-bound TreeView control



The following objects are used in the code below:

Data Access Object Library (3.5)


Form object named "frmDataTree"


TreeView control named "tvwDB"


CommandButton control named "cmdLoad"
To bind the Biblio.mdb Database to the TreeView control

Add a reference to the Data Access Objects (DAO 3.0) to your project.


Create module-level variables for the Database and Node objects.
In the Form Load event, set the Database object variable to the Biblio database using the OpenDatabase statement.


Create the top level node object using the Nodes collection’s Add method.
In a CommandButton's Click event, create two Recordset variables and set them to the Publishers and Titles tables.


Use the "Do Until" statement to create a Node object for each publisher in the table.


For each publisher, check the PubID field in the Titles recordset for matches; add a child node for each match.
Add a Reference to the Data Access Objects (DAO 3.5) to Your Project
To bind a database to the TreeView control, you must first add a reference to the current version of Data Access Objects (DAO).

Create Module-Level Variables for the Database Object and Node Object
Because you will want to access the Biblio.mdb database several times during a single session, it's more efficient to keep a single copy of the database open by creating a module-level Database object. Thereafter, you can access the database without reopening it. In the Declarations section of the form, write:

Private mDbBiblio As Database

If you want the database to be used by other modules, use the Public statement, and rename the variable to reflect its global status, i.e., gDbBiblio.

When creating Node objects, use the Set statement (shown below) with a variable of type Node.

Dim TempNode As Node
Set TempNode = tvwDB.Nodes.Add()

While you can create the variable whenever you add Node objects, it is more efficient to declare a single module-level Node object variable once and use it to create all Node objects. Again in the Declarations section, write:

Private mNode As Node

Set the Database object variable to the Biblio database using the OpenDatabase statement
The Form object's Load event can be used to initialize the Database variable. The code for this would be:

Set mDbBiblio = DBEngine.OpenDatabase("BIBLIO.MDB")

After you have successfully initialized the Database object variable, you can freely access it from anywhere within the code module.

Form Load Event: Create the Top Level Node Object Using the Nodes Collection's Add Method
Now that the Database object variable has been initialized with the Biblio database, you may want to create the first node in the tree and assign it the name of the open database. You must first use the Node collection's Add method to create the first Node object. You should also use the Set statement with the mNode object variable, as shown below:

Set mNode = tvwDB.Nodes.Add() ' Create the first node.
mNode.Text = mDbBiblio.Name

Notice that in the code above, using the Set statement simultaneously created the Node while assigning it to the mNode object variable. Since the mNode variable now contains the newly created Node object, you can assign various properties to the new Node. In the above case, the name of the Database (i.e. the Database object's Name property) has been assigned to the new node's Text property.

CommandButton Click Event: Create Two Recordset Variables and Set Them to the Publishers and Titles Tables
The present scenario assumes that a button called "cmdLoad" exists, and that when the user clicks it, the TreeView control is populated with two tables from the Biblio database. To accomplish this task, you must first declare two DAO object variables in the button's Click event. The first variable, rsPublishers, will contain the Publishers table. The second, rsTitles, will contain the Titles table. The code below declares the two variables then uses the OpenRecordSet method to assign the tables to the variables:

Dim rsPublishers as Recordset
Dim rsTitles as Recordset

set rsPublishers = mDbBiblio. _
OpenRecordset("Publishers", dbOpenDynaset)
set rsTitles = mDbBiblio. _
OpenRecordset("titles", dbOpenDynaset)



Use the Do Until Statement to Create a Node Object for Each Publisher in the Table
Now that you have two open recordsets, you can iterate through each recordset, create a Node object, and assign an appropriate value to the object’s Text property. First, you must iterate through the Publishers table and create a Node object for each Publisher in the table.

The simplified code below can be stated as, "Do until the End of the Recordset: create a Node object and assign its Text property the value of the Title field; move to the next record and repeat":

Do Until rsPublishers.EOF
set mNode = tvwDB.Nodes.Add(1, tvwChild)
mNode.Text = rsPublishers!Name
rsPublishers.MoveNext
Loop



Note that in the Add method above, we used two arguments. The first argument (1) is the Index property of the Node to which we want to add a Child node. That is, we want all the Publisher nodes to be children of the first (root) node (which was created in the Form's Load event). The second argument uses a constant (tvwChild) that specifies the new Node will be a child node of the Node with index "1."

For Each Publisher, Check the PubID Field in the Titles Recordset for Matches; Add a Child Node for each Match
The code above will populate the first level of the TreeView with the contents of the Publishers table. However, we wish to go one level deeper and add child nodes to each Publisher node. Each child node will then represent a book that the Publisher prints.

To accomplish this, while we have the reference to the newly created Publisher node (mNode), we need to iterate through the Titles recordset and check every record's PubID field. If that field corresponds to the PubID field in the Publishers recordset, the book is published by our present publisher. But before we can add a node to mNode, we must first assign a variable (intIndex) the value of mNode's Index property, as shown below:

intIndex = mNode.Index

We can now use this variable in the Add method, which requires the Index property of the Node object to which a child node is being added:

Set mNode = tvwDB.Nodes.Add(intIndex, tvwChild)

The simplified code below can be stated as, "Do until the End of the Recordset: create a child Node object and assign its Text property the value of the Title field; move to the next record and repeat":

Do Until rsTitles.EOF
If rsPublishers!PubID = rsTitles!PubID then
set mNode = tvwDB.Nodes.Add(intIndex, tvwChild)
mNode.Text = rsTitles!Title ' Text property.
End If
Loop



Completing the Code
The code above shows the basic strategy for populating a table with two related tables. The complete code is shown below:

' Be sure to set References to DAO 3.5
' In the Declarations section, declare module-level
' object variables:
private mDbBiblio as Database
private mNode as Node

private Sub Form_Load()
' In Form_Load event, set object variable and
' create first Node object of TreeView control.

set mDbBiblio = DBEngine.Workspaces(0). _
OpenDatabase("BIBLIO.MDB")

tvwDB.Sorted = true
set mNode = tvwDB.Nodes.Add()
mNode.Text = "Publishers"
mNode.Tag = mDbBiblio.Name ' set Tag property.
mNode.Image = "closed" ' set Image
' property.
End Sub

private Sub cmdLoad_Click()
' Declare DAO object variables and assign
' recordsets to them.
Dim rsPublishers as Recordset
Dim rsTitles as Recordset
set rsPublishers = mDbBiblio. _
OpenRecordset("Publishers", dbOpenDynaset)
set rsTitles = mDbBiblio. _
OpenRecordset("titles", dbOpenDynaset)

' Go to the first record.
rsPublishers.MoveFirst

Dim intIndex as Integer ' Variable for index.

' Do until the last record (EOF): add a Node
' object and use the Name field as the
' new Node object's text.
Do Until rsPublishers.EOF
set mNode = tvwDB.Nodes.Add(1, tvwChild)
mNode.Text = rsPublishers!Name
mNode.Tag = "Publisher" ' Tag identifies the
' table.
' Assign a unique ID to the Key
mNode.Key = CInt(rsPublishers!PubID) & " ID"
' set the variable intIndex to the Index
' property of the newly created Node. Use this
' variable to add child Node objects to the
' present Node.
intIndex = mNode.Index
' While on this record, search the Title table
' for any occurence of the same PubID in the
' Titles recordset. If one is found, add a Node
' object to the TreeView control, and set the
' new Node object properties with the found
' record's Title, ISBN and Author fields.
Do Until rsTitles.EOF
If rsPublishers!PubID = rsTitles!PubID then
set mNode = tvwDB.Nodes. _
Add(intIndex, tvwChild)
mNode.Text = rsTitles!Title ' Text.
mNode.Key = rsTitles!ISBN ' Unique ID.
mNode.Tag = "Authors" ' Table name.
mNode.Image = "leaf" ' Image.
End If
rsTitles.MoveNext ' next record in Titles.
Loop
' Reset rsTitles to first Titles record.
rsTitles.MoveFirst
' Move to next Publisher record.
rsPublishers.MoveNext
Loop
End Sub



Enhancing the Code
The example can be improved by using a SQL statement to create a smaller "Titles" recordset. The code below creates a recordset of only the records which have the same PubID value:

Set rsTitles = mDbBiblio.OpenRecordset _
("select * from Titles Where PubID = " & _
rsPublishers!PubID)

The code can then iterate through this smaller recordset more efficiently. The modified code is shown below:

private Sub cmdLoad_Click()
Dim rsPublishers as Recordset
Dim rsTitles as Recordset
set rsPublishers = mDbBiblio. _
OpenRecordset("Publishers", dbOpenDynaset)
Dim intIndex
Do Until rsPublishers.EOF
set mNode = tvwDB.Nodes.Add(1, tvwChild)
mNode.Text = rsPublishers!Name
mNode.Tag = "Publisher" ' Identifies the table.
mNode.Key = rsPublishers!PubID & " ID"
mNode.Image = "closed"
intIndex = mNode.Index
' While on this record, create a recordset
' using a query that finds only titles that have
' the same PubID. for each record in the
' resulting recordset, add a Node object to the
' TreeView control, and set the new Node object
' properties with the record's Title, ISBN and
' Author fields.
set rsTitles = mDbBiblio.OpenRecordset _
("select * from Titles Where PubID = " & _
rsPublishers!PubID)
Do Until rsTitles.EOF
set mNode = tvwDB.Nodes. _
Add(intIndex, tvwChild)
mNode.Text = rsTitles!TITLE ' Text.
mNode.Key = rsTitles!ISBN ' Unique ID.
mNode.Tag = "Authors" ' Table name.
mNode.Image = "smlBook" ' Image.
' Move to next record in rsTitles.
rsTitles.MoveNext
Loop
' Move to next Publishers record.
rsPublishers.MoveNext
Loop
End Sub




Special thanks to Lothar "the Great" Haensler, Tom Archer, Chris Eastwood, Bruno Paris and all the other wonderful people who made and make Codeguru a great place. Come back soon, you Gurus.