經過一段時間的努力,並參閱了很多大俠的源代碼,重新改造了一下TreeView控件。現將所有的源代碼全部公佈,以和朋友們共享。
'主要的功能有:
' 根據數據表中的記錄來添加節點;
' 每個節點都可以添加ToolTip提示;
' 可以得到當前選定節點的父節點或根節點,及其一些相關屬性;
' 可以拖動節點,並可自由設置拖動後的數據處理辦法;
' 可以通過編號直接定位到某個節點,也可以通過查找文本的辦法找到節點
'還需要改進的是:
' 1、圖片。根據記錄TJ值的不同,各個節點,可以使用不同的圖片;
' 2、複選框。如何控制各個節點的複選框:有些節點可以選中,有些則不選中;
' 如果父節點的複選框選中,則所有子節點都選中,取消父節點的複選框後,則所有的子節點都取消(還包括類似情況);
' 3、文本查找。在樹中查找文本,如果找到後,應該將該節點展開,而目前,有時好象只能展開一部分;
' 4、加載速度。由於是根據數據表中記錄來添加節點,所以加載的速度比較慢,需要優化;
Imports System.Drawing
全新打造的最新的 TreeView 作者:錢波#Region " 全新打造的最新的 TreeView 作者:錢波 "
'主要的功能有:
' 根據數據表中的記錄來添加節點;
' 每個節點都可以添加ToolTip提示;
' 可以得到當前選定節點的父節點或根節點,及其一些相關屬性;
' 可以拖動節點,並可自由設置拖動後的數據處理辦法;
' 可以通過編號直接定位到某個節點,也可以通過查找文本的辦法找到節點
'主要的屬性有:
' BqMini1gRow '初始化時,獲取表的記錄行
' BqPdragType '初始化時,是否需要進行拖動
' BqpTooltip '指定提示信息
' BqPdragNode '返回拖動的節點對象
' BqPdragNo '返回拖動過的節點的數量
' BqPoSelectNode '返回當前選中的節點對象
' BqPoTableOut '返回當前數據表
' BqPallCounts '返回所有的節點數
' BqPfinCount '返回找到的節點數
' BqPtagBH '設置或返回當前選定項的Tag值,即編號
' BqPFindCount '根據文本查找定位節點,並返回找到的節點數
'獲取的節點 是我自己定義的一個的TreeNode對象,
'主要的屬性有:
' BqBh '節點的 編號
' BqBhFull '節點的 編號全稱
' BqImage '節點的 對應的ImageIndex的位置
' BqOneBh '節點的 根+末級編號
' BqOneText '節點的 根+末級名稱
' BqOneTextJc '節點的 根+末級簡稱
' BqNodeBoot '節點的 根節點
' BqNodeParent '節點的 父節點
' BqBhBoot '當前節點的根節點編號
' BqBhParent '當前節點的父節點編號
'
'主要的方法有:
' BqMini1del '刪除表中的記錄
' BqMini2add '添加記錄
' BqMini3node '開始添加節點
'主要的事件有:
' BqeSeNodeBar '外部設置,選擇節點後顯示節點信息
' BqeSeNodeBd '外部設置,選擇節點後綁定數據
' BqeNodeDrop '拖動完成後應該執行的操作
' BqeNodeFind '完成查找後應該執行的操作
'
'例如:
' Dim r1, r0 As DataRow
' With Me.BqUTre1.BqUTreeView1
' r0 = .BqMini1gRow
' .BqMini1del() '先清除BqUTre中的表中記錄
' For Each r1 In sMainTable.Rows
' r0("BP") = "" & r1.Item("BHparent").ToString '父編號
' r0("BH") = "" & r1.Item("BHmode").ToString'編號
' r0("MC") = "" & r1.Item("MCmode").ToString'名稱
' r0("Jc") = "" & r1.Item("JCmode").ToString'簡稱
' r0("Ti") = "" & r1.Item("HelpTip").ToString'幫助提示
' r0("Im") = "" & r1.Item("Image").ToString'對應的ImageIndex的位置
' r0("TJ") = "" & r1.Item("K_dele").ToString'條件
' .BqMini2add(r0)
' Next
' .BqPdragType = 1 '不能拖動
' .BqpTooltip = "功能模塊"
' .BqMini3node()
' End With
'還需要改進的是:
' 1、圖片。根據記錄TJ值的不同,各個節點,可以使用不同的圖片;
' 2、複選框。如何控制各個節點的複選框:有些節點可以選中,有些則不選中;
' 如果父節點的複選框選中,則所有子節點都選中,取消父節點的複選框後,則所有的子節點都取消(還包括類似情況);
' 3、文本查找。在樹中查找文本,如果找到後,應該將該節點展開,而目前,有時好象只能展開一部分;
' 4、加載速度。由於是根據數據表中記錄來添加節點,所以加載的速度比較慢,需要優化;
Public Class BqUTreeViewClass BqUTreeView
Inherits System.Windows.Forms.TreeView
Dim oBoot, oPare As BqTreNodeEx
'Dim oBoot, oPare As BqTreNodeEx
'Dim oSelect As BqTreNodeEx
Dim oDragNode As BqTreNodeEx '被拖動的節點
Dim lBM As BindingManagerBase
Dim ltb As DataTable = New DataTable("kTreTab") '只用於初始化時,建立新的表,並從外部傳入記錄
Dim mTb As DataTable '主要用於節點的設置,臨時表
Dim ltv As DataView
Dim lFGF As String '分隔符
''Dim lsFin As String '待查找的字符
Dim lsFins As Integer '查找結果的數量
''Dim lbFin As Boolean '是查找還是定位,lbFin = True '查找
''Dim lbSet As Boolean = True ',選擇後,是否需要重新取
Dim lbynDrag As Integer '是否可以拖動,1 內部拖動,2外部拖動,其它,不可以拖動
Dim lRecnoCounts As Integer
Dim oTooltip As New ToolTip
Dim lTooltip As String
Dim lslDrag As Integer = 0
Dim oHashTable As Hashtable '爲提高查找速度,而建立的
Public Sub New()Sub New()
MyBase.New()
Call TableCreat() '錢波加的,新建本類則就建立數據表
End Sub
Public Event BqeSeNodeBar() '外部設置,選擇節點後顯示節點信息
Public Event BqeSeNodeBd() '外部設置,選擇節點後綁定數據
Public Event BqeNodeDrop() '拖動完成後應該執行的操作
Public Event BqeNodeFind() '完成查找後應該執行的操作
Dim kkk, n As Integer
Public Sub BqMini1del()Sub BqMini1del()
ltb.Rows.Clear()
End Sub '刪除表中的記錄
Public Sub BqMini3node()Sub BqMini3node()
kkk = System.Environment.TickCount
Debug.WriteLine(Me.Name + " 在tree中,TreNodesAdd 開始:" + kkk.ToString)
lRecnoCounts = ltb.Rows.Count
If lRecnoCounts > 0 Then
Call TreNodesAdd()
End If
'lbSet = True
If lbynDrag = 1 Or lbynDrag = 2 Then
Me.AllowDrop = True
Else
Me.AllowDrop = False
End If
Me.AllowDrop = IIf(lbynDrag = 1, True, False)
Me.SelectedNode = Me.TopNode ' Me.Nodes.Item(0)
Me.HideSelection = False
n = System.Math.Abs(System.Environment.TickCount - kkk)
Debug.WriteLine(Me.Name + "在tree中,TreNodesAdd 結束:" + n.ToString)
End Sub '第一次用 ,開始添加節點
Public Sub BqMini2add()Sub BqMini2add(ByVal oDataRow As DataRow)
Try
Dim r As Array
r = oDataRow.ItemArray
ltb.Rows.Add(r)
Catch ex As Exception
End Try
End Sub '添加記錄
Public ReadOnly Property BqMini1gRow()Property BqMini1gRow() As DataRow
Get
Dim r As DataRow
r = ltb.Clone.NewRow
Return r
End Get
End Property '初始化時,獲取表的記錄行
Public ReadOnly Property BqPdragNode()Property BqPdragNode() As BqTreNodeEx
Get
Return oDragNode
End Get
End Property '返回拖動的節點對象
Public ReadOnly Property BqPdragNo()Property BqPdragNo() As Integer
Get
Return lslDrag
End Get
End Property '返回拖動過的節點的數量
Public ReadOnly Property BqPoSelectNode()Property BqPoSelectNode() As BqTreNodeEx
Get
Return Me.SelectedNode 'oSelect
End Get
End Property '返回當前選中的節點對象
Public ReadOnly Property BqPoTableOut()Property BqPoTableOut() As DataTable
Get
Return mTb
End Get
End Property '返回當前數據表
Public ReadOnly Property BqPallCounts()Property BqPallCounts() As Integer
Get
Return lRecnoCounts
End Get
End Property '返回所有的節點數
Public ReadOnly Property BqPfinCount()Property BqPfinCount() As Integer
Get
Return lsFins
End Get
End Property '返回找到的節點數
Public ReadOnly Property BqPFindCount()Property BqPFindCount(ByVal sText As String) As Integer
Get
Try
If Len(Trim(sText)) <= 0 Then
Exit Property '如果傳入的值爲空,則退出
End If
Me.CollapseAll()
Me.ForeColor = Color.Black '顏色設爲默認:黑
Dim o, e As BqTreNodeEx
Dim lEnumerator As IDictionaryEnumerator = oHashTable.GetEnumerator()
lsFins = 0
lEnumerator.Reset()
While lEnumerator.MoveNext()
o = lEnumerator.Value
o.ForeColor = Color.Black '顏色設爲默認:黑
If InStr(o.Text, Trim(sText)) > 0 Then
lsFins = lsFins + 1
Debug.WriteLine(o.Text)
If lsFins = 1 Then
e = o
End If
o.ForeColor = Color.Red
If IsNothing(o.BqNodeParent) Then
o.Expand()
Else
o.BqNodeParent.Expand()
End If
End If
End While
If lsFins > 0 Then
Me.SelectedNode = e '只選中第一個
RaiseEvent BqeNodeFind()
End If
Return lsFins
Catch ex As Exception
End Try
End Get
End Property
Public WriteOnly Property BqPdragType()Property BqPdragType() As Integer '設置是否可以拖動
Set(ByVal Value As Integer)
lbynDrag = IIf(Value = 1 Or 2, Value, 0) '0表示不能拖動,1自己內部拖動,2拖到外部
End Set
End Property '初始化時,是否需要進行拖動
Public Property BqpTooltip()Property BqpTooltip() As String
Get
Return lTooltip
End Get
Set(ByVal Value As String)
lTooltip = Value
Me.oTooltip.SetToolTip(Me, Value)
End Set
End Property '指定提示信息
Public WriteOnly Property BqPtagBH()Property BqPtagBH() As String
'Get
' If Not IsNothing(oSelect) Then
' Return oSelect.BqBh
' Else
' Return ""
' End If
'End Get
Set(ByVal Value As String)
'lsFin = Value
'lsFins = 0
'lbFin = False '定位
'lbSet = False
'Call SetT()
'lbSet = True
Try
If Len(Trim(Value)) <= 0 Then
Exit Property '如果傳入的值爲空,則退出
End If
Dim o As BqTreNodeEx
Dim lEnumerator As IDictionaryEnumerator = oHashTable.GetEnumerator()
lsFins = 0
lEnumerator.Reset()
While lEnumerator.MoveNext()
o = lEnumerator.Value
o.ForeColor = Color.Black '顏色設爲默認:黑
End While
o = oHashTable.Item(Trim(Value))
Me.CollapseAll()
Me.SelectedNode = o
o.ForeColor = Color.Cyan.Blue '定位顏色設爲:
o.Expand()
RaiseEvent BqeSeNodeBar()
Catch ex As Exception
End Try
End Set
End Property '設置或返回當前選定項的Tag值,即編號
'Public Function BqMTreFind(ByVal sTag As String) As Integer
' 'lsFin = sTag
' 'lsFins = 0
' 'lbFin = True '查找 文本
' 'lbSet = False '查找過程中,選擇節點後不重新取數
' 'Call SetT()
' 'lbSet = True
' 'BqMTreFind = lsFins
' 'RaiseEvent BqeNodeFind()
'End Function
Private Sub TableCreat()Sub TableCreat() '建表
Try
ltb.Rows.Clear()
With ltb.Columns
.Add("BP", Type.GetType("System.String")) '父編號
.Add("BH", Type.GetType("System.String")) '編號
.Add("MC", Type.GetType("System.String")) '名稱
.Add("Jc", Type.GetType("System.String")) '簡稱
.Add("Ti", Type.GetType("System.String")) '幫助提示
.Add("Im", Type.GetType("System.String")) '對應的ImageIndex的位置
.Add("TJ", Type.GetType("System.String")) '條件
'以下的字段,只在內部才進行設置其值
.Add("OB", Type.GetType("System.String")) '內部計算其值: 根+自己的編號
.Add("OJ", Type.GetType("System.String")) '內部計算其值: 根簡稱+自己的簡稱
.Add("OT", Type.GetType("System.String")) '內部計算其值: 根+自己的名稱
.Add("BB", Type.GetType("System.String")) '內部計算其值: 根節點編號
.Add("FB", Type.GetType("System.String")) '內部計算其值: 編號全稱
.Add("FT", Type.GetType("System.String")) '內部計算其值: 全稱,字符
.Add("JB", Type.GetType("System.String")) '內部計算其值: 級別,從一開始算
.Add("MJ", Type.GetType("System.Boolean")) '內部計算其值: 末級標誌
End With
Dim lc(0) As DataColumn
lc(0) = ltb.Columns("BH")
ltb.PrimaryKey = lc '編號必須唯一,這是每個節點的標誌
Catch ex As Exception
End Try
End Sub
Private Sub TreNodesAdd()Sub TreNodesAdd()
Try
Me.Nodes.Clear()
Dim lDataset As New Data.DataSet
mTb = New DataTable
mTb.Rows.Clear()
mTb.Columns.Clear()
mTb = ltb.Copy '不能直接用lTb這個表,因爲,重新添加節點時,會提示“表已經在另一個數據集DataSet中
oHashTable = New Hashtable(mTb.Rows.Count) '初始化集合大小
ltv = mTb.DefaultView
ltv.Sort = "BH"
lBM = BindingContext(ltv)
lDataset.Clear()
lDataset.Relations.Clear()
lDataset.EnforceConstraints = False '在嘗試執行任何更新操作時是否遵循約束規則
lDataset.Tables.Add(mTb)
Dim dr1 As New DataRelation("self", mTb.Columns("BH"), mTb.Columns("BP"))
lDataset.Relations.Add(dr1)
'n = System.Math.Abs(System.Environment.TickCount - kkk)
'Debug.WriteLine(Me.Name + " 在tree中,建立關聯:" + n.ToString)
Dim r1 As DataRow
Dim sP As String
lFGF = Me.PathSeparator.Trim
lFGF = IIf(lFGF.Length <> 1, "", lFGF)
For Each r1 In mTb.Rows
sP = "" & r1.Item("BP").ToString
If sP = "" Then '根
TreAdd(r1, Nothing)
End If
Next
'n = System.Math.Abs(System.Environment.TickCount - kkk)
'Debug.WriteLine(Me.Name + " 在tree中,結點加完:" + n.ToString)
'節點添加完成後,就可以顯示記錄的內容了
lDataset.Relations.Clear() ' 外傳出記錄時,不需要加關聯
Catch ex As Exception
MMSeRRor(ex)
End Try
End Sub
Private Sub TreAdd()Sub TreAdd(ByVal r As DataRow, ByVal item As BqTreNodeEx)
Try
Dim mi As New BqTreNodeEx
Dim lmMc As String
lmMc = Trim("" & r.Item("MC").ToString) '名稱,如果名稱爲 "減號 -",表示分隔符
If Microsoft.VisualBasic.Left(lmMc, 1) = "-" Then '在菜單名稱中,左邊第一個字符爲 - ,則表示分隔符
mi.Text = "-----分隔符-----"
Else
mi.Text = lmMc
End If
mi.BqBh = "" & r.Item("BH").ToString '編號
'mi.BqParentBh = "" & r.Item("BP").ToString '上級編號
mi.BqImage = "" & r.Item("im").ToString
mi.BqTip = "" & r.Item("Ti").ToString
mi.Checked = IIf(r.Item("TJ").ToString = "True", True, False)
If item Is Nothing Then
Me.Nodes.Add(mi)
oHashTable.Add(mi.BqBh, mi)
oBoot = mi
'oPare = Nothing
'mi.BqBootBh = mi.BqBh
mi.BqBhFull = mi.BqBh
mi.BqOneBh = mi.BqBh
mi.BqOneText = mi.Text
mi.BqOneTextJc = "" & r.Item("Jc").ToString
mi.BqNodeBoot = Nothing
'mi.BqNodeParent = Nothing
Else
item.Nodes.Add(mi)
oHashTable.Add(mi.BqBh, mi)
oPare = item
'mi.BqBootBh = oBoot.BqBh
mi.BqBhFull = oPare.BqBhFull + lFGF + mi.BqBh
mi.BqOneBh = oBoot.BqBh + lFGF + mi.BqBh
mi.BqOneText = oBoot.Text + lFGF + mi.Text
mi.BqOneTextJc = IIf(oBoot.BqOneTextJc.Length < 1, oBoot.Text, oBoot.BqOneTextJc) + lFGF + mi.Text
mi.BqNodeBoot = oBoot
'mi.BqNodeParent = oPare
End If
Dim n As Integer = 0
Dim s As String
lmMc = mi.BqBhFull
s = Replace(lmMc, lFGF, "") '計算級別
n = lmMc.Length - s.Length
mi.BqPjb = (n + 1).ToString
r("OB") = mi.BqOneBh
r("OT") = mi.BqOneText
r("OJ") = mi.BqOneTextJc
r("BB") = mi.BqBhBoot
r("FB") = mi.BqBhFull
r("FT") = mi.FullPath
r("JB") = (n + 1).ToString
'r("Mj") = False
r("Mj") = IIf(r.GetChildRows("self", DataRowVersion.Current).GetUpperBound(0) > -1, False, True)
Dim r2 As DataRow
For Each r2 In r.GetChildRows("self")
TreAdd(r2, mi)
Next
Catch ex As Exception
End Try
End Sub
'Private Sub Sel(ByVal e As BqTreNodeEx)
' Try
' RaiseEvent BqeSeNodeBar()
' Catch ex As Exception
' End Try
'End Sub '選擇後,得到當前選擇項的信息
'Private Sub SelF(ByVal n1 As BqTreNodeEx)
' n1.ForeColor = Color.Black '顏色設爲默認:黑
' Dim tj As Boolean = False
' If lbFin = False Then '定位
' If n1.BqBh = lsFin Then
' n1.ForeColor = Color.Cyan.Blue '定位顏色設爲:
' n1.Expand()
' Me.SelectedNode = n1
' Call Sel(n1) '定位後可以得到當前節點的值
' Exit Sub
' End If
' Else '在文本中查找
' If InStr(n1.Text, lsFin) > 0 Then
' n1.ForeColor = Color.Red
' lsFins = lsFins + 1
' lbSet = IIf(lsFins = 1, True, False) '還是要選擇中第一個
' n1.Expand()
' Me.SelectedNode = n1
' End If
' End If
' Dim n2 As BqTreNodeEx
' For Each n2 In n1.Nodes
' SelF(n2)
' Next
'End Sub
'Private Sub SetT()
' Dim n As BqTreNodeEx
' Me.Visible = False
' Me.CollapseAll()
' For Each n In Me.Nodes
' SelF(n)
' Next
' Me.Visible = True
'End Sub
Private Function TwoP()Function TwoP(ByVal node1 As BqTreNodeEx, ByVal node2 As BqTreNodeEx) As Boolean
' 檢查第二個節點的父節點。
If node2.Parent Is Nothing Then
Return False
End If
If node2.Parent.Equals(node1) Then
Return True
End If
' 如果父節點並不是 Null 或是等於第一個節點,則使用
' 第二個節點的父節點來遞迴調用 TwoP 方法。
Return TwoP(node1, node2.Parent)
End Function
Private Sub BqUTreeView_AfterSelect()Sub BqUTreeView_AfterSelect(ByVal sender As Object, ByVal e As TreeViewEventArgs) Handles MyBase.AfterSelect
'oSelect = Me.SelectedNode
RaiseEvent BqeSeNodeBar()
RaiseEvent BqeSeNodeBd()
'If lbSet Then
' Dim o As BqTreNodeEx
' o = CType(e.Node, BqTreNodeEx)
' oSelect = o '當前節點
' RaiseEvent BqeSeNodeBar()
' 'Call Sel(o)
' RaiseEvent BqeSeNodeBd()
'End If
End Sub
Private Sub BqUTreeView_MouseMove()Sub BqUTreeView_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
Dim n As BqTreNodeEx
n = Me.GetNodeAt(e.X, e.Y) ' 確認鼠標指標目前是位於哪一個節點之上。
If Not (n Is Nothing) Then ' 檢查鼠標指標所停駐之處是否真的是一個節點。
Dim s As String
s = n.BqTip
s = IIf(n.BqTip.Length < 1, n.FullPath, n.BqTip)
If (s <> oTooltip.GetToolTip(Me)) Then ' 只有在需要改變工具提示文字時才更新 TreeView 控制項的工具提示文字。
oTooltip.SetToolTip(Me, s)
End If
Else
oTooltip.SetToolTip(Me, "") ' 鼠標指標並非停駐在一個節點之上,因此清除 TreeView 控制項的工具提示文字。
End If
End Sub
Private Sub BqUTreeView_ItemDrag()Sub BqUTreeView_ItemDrag(ByVal sender As Object, ByVal e As ItemDragEventArgs) Handles MyBase.ItemDrag
' 如果用戶是持續按着鼠標左鍵來拖曳節點,則將會移動節點。
If e.Button = MouseButtons.Left Then
DoDragDrop(e.Item, DragDropEffects.Move)
' 如果用戶是持續按着鼠標右鍵來拖曳節點,則將會複製節點。
'ElseIf e.Button = MouseButtons.Right Then
' DoDragDrop(e.Item, DragDropEffects.Copy) '這句話不用了,只能拖動,不能複製
End If
End Sub
Private Sub BqUTreeView_DragEnter()Sub BqUTreeView_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles MyBase.DragEnter
e.Effect = e.AllowedEffect
End Sub ' 將目標置放效果設定成在 ItemDrag 事件過程中所指定的效果。
Private Sub BqUTreeView_DragOver()Sub BqUTreeView_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles MyBase.DragOver
Dim targetPoint As Point ' 取得鼠標指標所在位置的工作區座標(Client Coordinate)。
targetPoint = CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
' 選取鼠標指標所在位置之下的節點。
CType(sender, TreeView).SelectedNode = CType(sender, TreeView).GetNodeAt(targetPoint)
End Sub ' 將鼠標指標所在位置之下的節點選取起來,以便標示出預期的置放位置。
Private Sub BqUTreeView_DragDrop()Sub BqUTreeView_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles MyBase.DragDrop
Dim targetPoint As Point ' 取得置放位置的工作區座標。
Dim targetNode As BqTreNodeEx ' 取得在置放位置的節點。
Dim draggedNode As BqTreNodeEx ' 取得被拖曳的節點。
oDragNode = Nothing
targetPoint = CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
targetNode = CType(sender, TreeView).GetNodeAt(targetPoint)
draggedNode = CType(e.Data.GetData(GetType(BqTreNodeEx)), BqTreNodeEx)
Dim lyn As Boolean = False '表示是否拖動成功
If targetNode Is Nothing Then '如果置放位置爲空,則可以加到根
If e.Effect = DragDropEffects.Move Then
draggedNode.Remove()
Me.Nodes.Add(draggedNode)
Me.CollapseAll()
lyn = True
End If
' 確認在置放位置的節點並不是被拖曳的節點或被拖曳之節點的子系。
ElseIf Not draggedNode.Equals(targetNode) AndAlso Not TwoP(draggedNode, targetNode) Then
' 如果這是一項移動操作,則將節點從目前的位置移除並將它添加至置放位置的節點中。
If e.Effect = DragDropEffects.Move Then
draggedNode.Remove()
targetNode.Nodes.Add(draggedNode)
targetNode.Expand()
lyn = True
' 如果這是一項複製操作,則複製被拖曳的節點並將它添加至置放位置的節點中。
ElseIf e.Effect = DragDropEffects.Copy Then
'在自射拖動過程中,複製要得到好幾份,所以不用這一個了 20060801錢波註明
Dim n As New BqTreNodeEx
n = CType(draggedNode.Clone(), BqTreNodeEx)
targetNode.Nodes.Add(n)
Me.CollapseAll()
targetNode.Expand()
lyn = True
End If
End If
If lyn = False Then Exit Sub '如果沒有拖動成功,則不執行以下命令
Try
Dim m As String
Dim n As Integer
m = draggedNode.BqBh
ltv.Sort = "BH"
n = ltv.Find(m)
lBM.Position = n
Dim rv As DataRowView = ltv.Item(lBM.Position)
Dim o As BqTreNodeEx
o = CType(draggedNode.Parent, BqTreNodeEx)
If IsNothing(o) Then '則拖動到根節點下了
rv.Row("BP") = ""
With draggedNode
.BqNodeBoot = Nothing
'.BqNodeParent = Nothing
.BqTip = "已經移動到新的位置。重新進入後,數據生效!"
.BackColor = Color.Coral
End With
ElseIf Not o Is draggedNode.BqNodeParent Then '如果移動前後,父節點不相同,即表示移動成功
rv.Row("BP") = o.BqBh
With draggedNode
.BqNodeBoot = Nothing
'.BqNodeParent = o
'.BqParentBh = o.BqBh
.BqTip = "已經移動到新的位置。重新進入後,數據生效!"
.BackColor = Color.Coral
End With
End If
oDragNode = draggedNode
lslDrag = lslDrag + 1
RaiseEvent BqeNodeDrop()
Catch ex As Exception
End Try
End Sub
End Class
#End Region
這是我自己定義的一個treenode對象,可以再改一改後就可以用#Region " 這是我自己定義的一個treenode對象,可以再改一改後就可以用"
Public Class BqTreNodeExClass BqTreNodeEx
Inherits System.Windows.Forms.TreeNode
Implements IDictionaryEnumerator
Private nodeEntry As DictionaryEntry
Private enumerator As IEnumerator
Dim oToolTip As System.Windows.Forms.ToolTip
Public Sub New()Sub New()
enumerator = MyBase.Nodes.GetEnumerator()
End Sub
'加入以下的屬性:編號,父編號,父節點(對象),全稱,編號全稱,根+末級編號,根+末級名稱,級次,
'這樣,可以對treeview中每一個節點進行設置,方便選擇後的處理
Dim lBh, lBhparent As String
Dim lFullBh, lFullText As String
Dim lOneBh, lOneText As String
Dim lBootBh, lTip As String
Dim lImage, lParentS As String
Dim lbNode, lpNode As BqTreNodeEx
Dim lOneTextJc As String
Public Property BqBh()Property BqBh() As String
Get
Return lBh
End Get
Set(ByVal Value As String)
lBh = Value
End Set
End Property '節點的 編號
Public Property BqBhFull()Property BqBhFull() As String
Get
Return lFullBh
End Get
Set(ByVal Value As String)
lFullBh = Value
End Set
End Property '節點的 編號全稱
Public Property BqImage()Property BqImage() As String
Get
Return lImage
End Get
Set(ByVal Value As String)
lImage = Value
End Set
End Property '節點的 對應的ImageIndex的位置
Public Property BqOneBh()Property BqOneBh() As String
Get
Return lOneBh
End Get
Set(ByVal Value As String)
lOneBh = Value
End Set
End Property '節點的 根+末級編號
Public Property BqOneText()Property BqOneText() As String
Get
Return lOneText
End Get
Set(ByVal Value As String)
lOneText = Value
End Set
End Property '節點的 根+末級名稱
Public Property BqOneTextJc()Property BqOneTextJc() As String
Get
Return lOneTextJc
End Get
Set(ByVal Value As String)
lOneTextJc = Value
End Set
End Property '節點的 根+末級簡稱
Public Property BqNodeBoot()Property BqNodeBoot() As BqTreNodeEx
Get
Return lbNode
End Get
Set(ByVal Value As BqTreNodeEx)
lbNode = Value
End Set
End Property '節點的 根節點
Public ReadOnly Property BqNodeParent()Property BqNodeParent() As BqTreNodeEx
Get
'''Dim o As BqTreNodeEx
''o = CType(Me.Parent, BqTreNodeEx)
Return CType(Me.Parent, BqTreNodeEx) ' lpNode
End Get
'Set(ByVal Value As BqTreNodeEx)
' lpNode = Value
'End Set
End Property '節點的 父節點
Public ReadOnly Property BqBhBoot()Property BqBhBoot() As String
Get '因爲有可能當前節點的根節點是nothing,所以將其編號設置爲"",以便於外部調用比較方便
If IsNothing(Me.BqNodeBoot) Then
Return ""
Else
Return Me.BqNodeBoot.BqBh
End If
'Return lBootBh
End Get
'Set(ByVal Value As String)
' lBootBh = Value
'End Set
End Property '當前節點的根節點編號
Public ReadOnly Property BqBhParent()Property BqBhParent() As String
Get '因爲有可能當前節點的父節點是nothing,所以將其編號設置爲"",以便於外部調用比較方便
If IsNothing(Me.Parent) Then
Return ""
Else
Dim o As BqTreNodeEx
o = CType(Me.Parent, BqTreNodeEx)
Return o.BqBh
End If
Return lBhparent
End Get
'Set(ByVal Value As String)
' lBhparent = Value
'End Set
End Property '當前節點的父節點編號
Public Property BqPjb()Property BqPjb() As String '級別
Get
Return lParentS
End Get
Set(ByVal Value As String)
lParentS = Value
End Set
End Property
Public Property BqTip()Property BqTip() As String
Get
Return lTip
End Get
Set(ByVal Value As String)
lTip = Value
End Set
End Property '節點的 幫助提示
Public Property NodeKey()Property NodeKey() As String
Get
Return nodeEntry.Key.ToString()
End Get
Set(ByVal Value As String)
nodeEntry.Key = Value
End Set
End Property
Public Property NodeValue()Property NodeValue() As Object
Get
Return nodeEntry.Value
End Get
Set(ByVal Value As Object)
nodeEntry.Value = Value
End Set
End Property
Public Overridable Overloads ReadOnly Property Entry()Property Entry() As DictionaryEntry Implements IDictionaryEnumerator.Entry
Get
Return nodeEntry
End Get
End Property
Public Overridable Overloads Function MoveNext()Function MoveNext() As Boolean Implements IDictionaryEnumerator.MoveNext
Dim Success As Boolean
Success = enumerator.MoveNext()
Return Success
End Function
Public Overridable Overloads ReadOnly Property Current()Property Current() As Object Implements IEnumerator.Current
Get
Return enumerator.Current
End Get
End Property
Public Overridable Overloads ReadOnly Property Key()Property Key() As Object Implements IDictionaryEnumerator.Key
Get
Return nodeEntry.Key
End Get
End Property
Public Overridable Overloads ReadOnly Property Value()Property Value() As Object Implements IDictionaryEnumerator.Value
Get
Return nodeEntry.Value
End Get
End Property
Public Overridable Overloads Sub Reset()Sub Reset() Implements IEnumerator.Reset
enumerator.Reset()
End Sub
End Class
#End Region