提要:在VB6中,常将TreeView用来表示层次数据,但相关的与数据库进行交互的代码,需要大量的采用手工编码;在VB.Net中,由于数据绑定功能的加强及语言特性的增强,可以很容易的实现TreeView与层次数据的绑定,本文将首先建立一个继承自TreeView的 dbTreeView,然后用一个单位(部门)的层次数据与dbTreeView进行数据绑定,并提供了与数据库进行交互的代码。
1、从层次数据的表达方式开始
在本例中,部门表(department)中有五个字段,如下表:
字段名 |
字段 |
类型说明 |
ID |
自动编号 |
Key |
Code |
String |
编码 |
Name |
String |
名称 |
PID |
Int |
父结点的ID |
CPtr |
boolean |
是否有子结点 |
2、继承自TreeNode的myTreeNode
在myTreeNode中,新增了三个属性,如下表:
属性名 |
类型 |
说明 |
Value |
Object |
Key |
PID |
Object |
父结点的ID |
CPtr |
Boolean |
是否有子结点 |
在Init事件中,根据传入的四个参数,设置这三个属性和Text属性。
3、将dbTreeView绑定到数据源
属性名 |
类型 |
说明 |
Datasource |
dataview |
dbTreeVIew的数据源使用dataview,而不是object |
Value |
Member |
string值成员(数据源[dataview]的列名) |
Display |
Member |
string显示(在Text中)成员 |
Pid |
Member |
string父ID成员 |
CPtr |
Member |
string是否有子结点 |
后四个属性对应myTreeNode的value,text,pid,cptr。
相关代码如下:
Protected Property DataSource() As Object |
设置DisplayMember属性的格式如:字段1;字段2;字段3… ,在设置属性时,将传来的参数转换为字符串数组mDisplayMember,在检索值时返回数据如:值1 值2 值3.…
Protected Overridable Function GetDisplay(ByVal Index As Integer) As Object |
其它检索值的函数请参见源程序。
生成树
UpdateTreeView调用私有方法FillTree来生成树,需要注意的,FillTree只是生成指定结点的子结点并将其添加到指定结点,而不是一次就将所有结点添加到树中,如果未指定结点(第一次填充时),只是添加顶层结点。
Private Sub FillTree(ByRef pnode As myTreeNode, Optional ByVal filter As String = "") |
在展开有子结点的结点前,删除所有子结点,再用FillTree为待展开结点新增子结点。
Private Sub dbTreeView_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles MyBase.BeforeExpand |
4、实现数据与绑定控件的同步
要实现两个方面的同步:
1、 其它绑定控件(如textbox等)应与TreeView当前结点所指向的记录位置一致。
Private Sub dbTreeView_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles MyBase.AfterSelect |
2、在其它绑定控件改变了数据源后,更新树结点,这个工作在触发CurrencyManager的PositionChanged事件时进行。
Public Sub cm_PositionChanged(ByVal sender As Object, ByVal e As System.EventArgs) |
使用dbTreeView
程序运行后界面如下:
相关代码请参见源程序,这里不做详述,需要注意的是删除操作并没有删除子结点,只是删除当前结点而已,删除子结点的工作应该在存储过程中递归实现,而不应放在前端。