手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网络编程>Asp.Net编程>列表

VB6.0设计真正实用的TreeView控件

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

  Else
   .DropHighlight = .HitTest(x, y)
  End If
 End With
 mfX = x
 mfY = y
 If y > 0 And y < 100 Then
  m_iScrollDir = -1
  Timer1.Enabled = True
 ElseIf y > (SmartTreeView.Height - 200) And _
  y < SmartTreeView.Height Then
  m_iScrollDir = 1
  Timer1.Enabled = True
 Else
  Timer1.Enabled = False
 End If
End Sub
  拖着节点经过其他可见的节点不存在什么问题,但要把节点拖到某个当前不在控件可见区域的节点就要复杂一些。为了实现这个功能,当鼠标拖着节点到达TreeView控件的顶部或底部时,我们必须强制TreeView滚动其可见区域。TVEdit工程利用了一个每200ms触发的Timer,以便分析当前鼠标指针所处的位置。如果鼠标拖着节点到达距离TreeView控件顶部或底部100 pixel的位置,控件显示的内容就必须滚动。有关这一技术的详细说明,有兴趣的读者可参见MSDN文章Q177743。

  SmartTreeView_OLEDragOver事件句柄有几行代码用来判断是否要滚动控件以及开启Timer,但实际的滚动操作由Timer的事件句柄完成。

  当用户拖着节点到达目的地后放开鼠标键,控件触发OLEDragDrop事件,这个事件句柄要提取出被拖动的节点,并把它放在当前高亮度显示的节点之下。前面我们把被拖动节点的Key放入了事件句柄的参数Data对象,现在可以利用这个Key方便地从Notes集合得到被拖动的节点,只要把这个节点的ParentNode属性设置成当前高亮度显示的节点,就完成了移动节点(及其所有子节点)的操作。注意被拖动的节点不能放入它自己的子节点之下,因为这会形成父子节点相互引用的循环引用关系。

Private Sub SmartTreeView_OLEDragDrop( _
Data As MSComctlLib.DataObject, Effect As Long, _
Button As Integer, Shift As Integer, x As Single, _
y As Single)

 Dim strKey As String
 Dim thisNode, DragNode As Node

 Set oNode = Me.SmartTreeView.HitTest(x, y)

 If Data.GetFormat(vbCFText) Then
  strKey = Data.GetData(vbCFText)
  Set oDragNode = SmartTreeView.Nodes(strKey)
  On Error Resume Next
  Set oDragNode.Parent = oNode
  If Err.Number = 35614 Then
   MsgBox "节点不能移动到此位置:不能创建循环引用关系。"
   On Error GoTo 0
  End If
  Set SmartTreeView.DropHighlight = Nothing
 End If
End Sub
  四、保存节点数据

  TreeView本身没有提供保存节点数据的Save方法,也没有从文件读取节点数据的Load方法,这些方法都要我们自己实现。保存TreeView数据最简单的形式是XML文件,因为层次型结构是XML固有的特征。我们将用MSXML组件来创建和保存XML文档,VB6默认不带这个组件,但你可以从MSDN下载。

  在VB中使用MSXML组件首先要把它加入工程:打开“工程”菜单,选择“引用”,在对话框中选中“Microsoft XML v3.0”组件。


          图二
  点击“保存”按钮,控件的当前数据将被保存为一个“扁平”XML文件(图二):每一个节点保存为一个XML元素,节点的属性作为XML元素的属性保存,节点之间的从属关系通过元素的ParentKey属性得以体现。下面是“保存”按钮点击事件句柄的代码。

Private Sub bttnSave_Click()
 Dim xmlDoc As DOMDocument30
 Set xmlDoc = New DOMDocument30

 Dim ElementNode As IXMLDOMElement
 Dim RootElementNode As IXMLDOMElement
 Set ElementNode = xmlDoc.createElement("NODES")
 Set RootElementNode = xmlDoc.appendChild(ElementNode)

 Dim TNode As Node
 Dim i As Integer
 For i = 1 To SmartTreeView.Nodes.Count
  Set TNode = SmartTreeView.Nodes(i)
  Set ElementNode = xmlDoc.createElement("NODE")
  ElementNode.setAttribute "Caption", TNode.Text
  ElementNode.setAttribute "Key", TNode.Key
  ElementNode.setAttribute "Tag", TNode.Tag
  If TNode.Parent Is Nothing Then
   ElementNode.setAttribute "ParentKey", ""
  Else
   ElementNode.setAttribute "ParentKey", TNode.Parent.Key
  End If
  RootElementNode.appendChild ElementNode
 Next
 xmlDoc.save ("C:\XMLNodes.xml")
End Sub
  bttnSave_Click事件句柄首先创建根元素,然后用一个For...Next循环遍历TreeView控件的节点集合,每次循环创建一个新的元素,提取节点的属性作为XML元素的属性。

  用“保存”按钮生成的XML文档虽然包含了重构TreeView所需的所有信息,但XML文档本身未能直观地显示出节点之间的从属关系。点击“保存(嵌套)”按钮可将TreeView的节点数据保存为另一种XML格式,如图三。


         图三
  新的嵌套XML格式更加直观地反映出节点之间的从属关系,虽然它在编程方面不一定比前面的“扁平”格式方便,但它显然更适合人阅读和理解。

  将节点数据保存为嵌套格式也同样要用到MSXML组件,但生成XML文档的过程略有变化。仔细观察嵌套XML文档的结构,可以发现它蕴含一种递归结构——节点“浙江省”同“绍兴”的关系,正如“绍兴”同“嵊州”的关系,因此,TVEdit工程用一个递归过程方便地生成了嵌套XML文档,具体的代码这里就不再说明。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!