Abstract: In VB6, Treeview is often used to represent hierarchical data. Code , Requires a large number of manual encoding; in VB. net, due to the enhancement of the Data Binding function and the enhancement of the language features, it is easy to bind the Treeview and hierarchical data. This article will first create a dbtreeview inherited from the Treeview, then, you can bind the hierarchical data of a unit (Department) to dbtreeview and provide code for interaction with the database.
1. Starting from the expression of hierarchical data
In this example, the department table contains five fields:
Field name |
Field |
Type description |
ID |
Automatic ID |
Key |
Code |
String |
Encoding |
Name |
String |
Name |
PID |
Int |
Parent node ID |
Cptr |
Boolean |
Indicates whether a subnode exists. |
2. mytreenode inherited from treenode
In mytreenode, three attributes are added, as shown in the following table:
Attribute name |
Type |
Description |
Value |
Object |
Key |
PID |
Object |
Parent node ID |
Cptr |
Boolean |
Indicates whether a subnode exists. |
In the init event, set these three attributes and text attributes based on the four parameters passed in.
3. Bind dbtreeview to the data source
Attribute name |
Type |
Description |
Datasource |
Dataview |
Dbtreeview data sources use dataview instead of Object |
Value |
Member |
String Value member (column name of the data source [dataview) |
Display |
Member |
String display (in text) member |
PID |
Member |
String parent ID Member |
Cptr |
Member |
Whether the string has subnodes |
The last four attributes correspond to the value, text, PID, and cptr of mytreenode.
The related code is as follows:
Protected property datasource () as object
Get
Return mdataview
End get
Set (byval value as object)
If value is nothing then
Else
Mdataview = Value
Cm = ctype (Me. bindingcontext (mdataview), currencymanager)
Updatetreeview ()
End if
End set
End Property
Protected property pidmember () as string
Get
Return mpidmember
End get
Set (byval value as string)
Mpidmember = Value
End set
End Property
Protected property displaymember () as string
Get
Return join (mdisplaymember, splitchar)
End get
Set (byval value as string)
Mdisplaymember = Split (value, splitchar)
End set
End Property
'Note: these attributes are all protected members and must be set in the init event:
Public sub Init (byval dispmember as string, byval valuemember as string, byval pidmember as string, byval cptrmember as string, byval datasource as dataview)
Me. valuemember = valuemember
Me. displaymember = dispmember
Me. pidmember = pidmember
Me. cptrmember = cptrmember
Me. datasource = datasource
'Use the maximum value. When adding a value, add value + 1 to ensure that the key value is unique.
Me. mdataview. Sort = me. valuemember
Me. m_maxid = me. getvalue (Me. mdataview. Count-1)
End sub
Set the displaymember attribute format, for example, field 1, Field 2, Field 3 ..., When setting properties, convert the transmitted parameters to the mdisplaymember string array. The returned data is: value 1, value 2, and value 3 ....
Protected overridable function getdisplay (byval index as integer) as object
Dim I as integer
Dim temp as string = ""
For I = 0 to mdisplaymember. Length-1
Temp = temp & IIF (I> 0, linkchar, "") & mdataview (INDEX) (mdisplaymember (I ))
Next
Return temp
End Function
For other functions to retrieve values, see SourceProgram.
Spanning Tree
Updatetreeview calls the private method filltree to generate a tree. Note that filltree only generates the child nodes of the specified node and adds them to the specified node, instead of adding all the nodes to the tree at a time, if no node is specified (when it is filled for the first time), only the top-level node is added.
Private sub filltree (byref pnode as mytreenode, optional byval filter as string = "")
Mdataview. rowfilter = Filter
Dim I as integer, icol as integer
Dim newnode as mytreenode
Removehandler cm. positionchanged, addressof cm_positionchanged
Me. beginupdate ()
For I = 0 to mdataview. Count ()-1
Newnode = new mytreenode (getdisplay (I), getvalue (I), getpid (I), getcptr (I ))
'When a child node exists, add an empty child node to the node.
If newnode. cptr then
Dim nullnode as new mytreenode ()
Nullnode. value = noexpandnodevalue
Newnode. nodes. Add (nullnode)
End if
If pnode is nothing then
Me. nodes. Clear ()
Me. nodes. Add (newnode)
Else
Pnode. nodes. Add (newnode)
End if
Next
Me. endupdate ()
Mdataview. rowfilter = ""
Addhandler cm. positionchanged, addressof cm_positionchanged
End sub
Before expanding a node with a child node, delete all child nodes and use filltree to add a child node for the node to be expanded.
Private sub dbtreeview_beforeexpand (byval sender as object, byval e as system. Windows. Forms. treeviewcanceleventargs) handles mybase. beforeexpand
'Exit directly when the beforeexpand event is caused by a new node.
If expandwhenaddnode then exit sub
'Update the subnode before expanding the node
Dim currentnode as mytreenode = ctype (E. node, mytreenode)
With currentnode
. Nodes. Clear ()
Filltree (currentnode, mpidmember & "=" & CINT (. Value ))
End
End sub
4. synchronize data with bound controls
To achieve synchronization in two aspects:
1. Other bound controls (such as textbox) should be consistent with the record location pointed to by the current node of the Treeview.
Private sub dbtreeview_afterselect (byval sender as object, byval e as system. Windows. Forms. treevieweventargs) handles mybase. afterselect
If E. node is nothing then exit sub
'Locate position
Cm. Position = getposition (ctype (E. node, mytreenode). value)
If allowedit then
Oldnode = E. Node
Oldpos = cm. Position
End if
End sub
2. After other bound controls change the data source, update the tree node. This operation is performed when the positionchanged event of currencymanager is triggered.
Public sub cm_positionchanged (byval sender as object, byval e as system. eventargs)
If ctype (Me. selectednode, mytreenode). value <> getvalue (CM. Position) then
Debug. writeline ("current node isn' t correct point to currencymanager. Position! ")
Me. selectednode = findnodebyvalue (getvalue (CM. position), me. nodes)
End if
If allowedit then
If me. selectednode is nothing andalso cm. Position = cm. Count-1 then
'When a record is added, the tree node is added.
If ctype (CM. Current, datarowview). isnew then
Me. selectednode = addnode (CM. position)
Exit sub
End if
End if
If not oldnode is nothing then
If ctype (oldnode, mytreenode). value = getvalue (oldpos) then
'Update the old Node
Oldnode. Text = getdisplay (oldpos)
Else
End if
End if
End if
End sub
Use dbtreeview
After running the program, the interface is as follows:
For more information about the relevant code, see the source program. We will not describe it here. Note that the delete operation does not delete the child nodes, but only deletes the current node, deleting a child node should be implemented recursively In the stored procedure, rather than on the front end.