416 lines
11 KiB
VB.net
416 lines
11 KiB
VB.net
|
|
Option Explicit On
|
|||
|
|
|
|||
|
|
Public Class Node
|
|||
|
|
|
|||
|
|
#Region "公共变量"
|
|||
|
|
|
|||
|
|
Private mstrKey As String
|
|||
|
|
Private mstrText As String
|
|||
|
|
Private mstrTag As String
|
|||
|
|
Private mblnExpanded As Boolean
|
|||
|
|
Private mintChildrenCount As Integer
|
|||
|
|
Private mintVisibleNodesCount As Integer
|
|||
|
|
Private mintLevel As Integer
|
|||
|
|
Private mobjNodes As Nodes
|
|||
|
|
Private mobjParent As Node
|
|||
|
|
Private mobjPrevNode As Node
|
|||
|
|
Private mobjNextNode As Node
|
|||
|
|
|
|||
|
|
#End Region
|
|||
|
|
#Region "Friend 属性"
|
|||
|
|
|
|||
|
|
Friend ReadOnly Property AbsIndex() As Integer
|
|||
|
|
Get
|
|||
|
|
Dim i As Integer
|
|||
|
|
Dim tmpNode As Node
|
|||
|
|
tmpNode = Me
|
|||
|
|
i = 1
|
|||
|
|
Do
|
|||
|
|
If tmpNode.PrevNode Is Nothing Then
|
|||
|
|
If mobjParent IsNot Nothing Then
|
|||
|
|
i = i + mobjParent.AbsIndex
|
|||
|
|
End If
|
|||
|
|
Exit Do
|
|||
|
|
Else
|
|||
|
|
tmpNode = tmpNode.PrevNode
|
|||
|
|
i = i + 1 + tmpNode.ChildrenCount
|
|||
|
|
End If
|
|||
|
|
Loop
|
|||
|
|
Return i
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Friend Property PrevNode() As Node
|
|||
|
|
Get
|
|||
|
|
Return mobjPrevNode
|
|||
|
|
End Get
|
|||
|
|
Set(ByVal value As Node)
|
|||
|
|
mobjPrevNode = value
|
|||
|
|
End Set
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Friend Property NextNode() As Node
|
|||
|
|
Get
|
|||
|
|
Return mobjNextNode
|
|||
|
|
End Get
|
|||
|
|
Set(ByVal value As Node)
|
|||
|
|
mobjNextNode = value
|
|||
|
|
End Set
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
Friend ReadOnly Property Root() As Node
|
|||
|
|
Get
|
|||
|
|
If mobjParent Is Nothing Then
|
|||
|
|
Return Me
|
|||
|
|
Else
|
|||
|
|
Return mobjParent.Root
|
|||
|
|
End If
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Friend ReadOnly Property VisibleNodesCount() As Integer
|
|||
|
|
Get
|
|||
|
|
Return mintVisibleNodesCount
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
#End Region
|
|||
|
|
#Region "Public属性"
|
|||
|
|
|
|||
|
|
Public Property Parent() As Node
|
|||
|
|
Get
|
|||
|
|
Return mobjParent
|
|||
|
|
End Get
|
|||
|
|
Set(ByVal value As Node)
|
|||
|
|
mobjParent = value
|
|||
|
|
End Set
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public ReadOnly Property Level() As Integer
|
|||
|
|
Get
|
|||
|
|
Return mintLevel
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public Property Key() As String
|
|||
|
|
Get
|
|||
|
|
Return mstrKey
|
|||
|
|
End Get
|
|||
|
|
Set(ByVal Value As String)
|
|||
|
|
mstrKey = Value
|
|||
|
|
End Set
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public Property Text() As String
|
|||
|
|
Get
|
|||
|
|
Return mstrText
|
|||
|
|
End Get
|
|||
|
|
Set(ByVal Value As String)
|
|||
|
|
mstrText = Value
|
|||
|
|
End Set
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public Property Tag() As String
|
|||
|
|
Get
|
|||
|
|
Return mstrTag
|
|||
|
|
End Get
|
|||
|
|
Set(ByVal Value As String)
|
|||
|
|
mstrTag = Value
|
|||
|
|
End Set
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public ReadOnly Property HasChildren() As Boolean
|
|||
|
|
Get
|
|||
|
|
If mobjNodes Is Nothing Then
|
|||
|
|
Return False
|
|||
|
|
Else
|
|||
|
|
Return True
|
|||
|
|
End If
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public ReadOnly Property Nodes() As Nodes
|
|||
|
|
Get
|
|||
|
|
If mobjNodes Is Nothing Then
|
|||
|
|
mobjNodes = New Nodes(Me)
|
|||
|
|
End If
|
|||
|
|
Return mobjNodes
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public ReadOnly Property Expanded() As Boolean
|
|||
|
|
Get
|
|||
|
|
Return mblnExpanded
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public ReadOnly Property Visible() As Boolean
|
|||
|
|
Get
|
|||
|
|
If mintLevel = 0 Then
|
|||
|
|
Return True
|
|||
|
|
End If
|
|||
|
|
Dim i As Integer
|
|||
|
|
Dim tmpNode As Node
|
|||
|
|
tmpNode = mobjParent
|
|||
|
|
For i = mintLevel To 1 Step -1
|
|||
|
|
If Not tmpNode.Expanded Then
|
|||
|
|
Return False
|
|||
|
|
End If
|
|||
|
|
tmpNode = tmpNode.Parent
|
|||
|
|
Next
|
|||
|
|
Return True
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
Public ReadOnly Property ChildrenCount() As Integer
|
|||
|
|
Get
|
|||
|
|
Return mintChildrenCount
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
#End Region
|
|||
|
|
#Region "Private方法"
|
|||
|
|
|
|||
|
|
Private Sub CopyNode(ByVal SourceNode As Node, ByVal TargetNode As Node)
|
|||
|
|
'复制所有的子节点
|
|||
|
|
If Not SourceNode.Expanded Then
|
|||
|
|
TargetNode.Collapse()
|
|||
|
|
End If
|
|||
|
|
If SourceNode.ChildrenCount > 0 Then
|
|||
|
|
Dim i As Integer
|
|||
|
|
Dim strText As String
|
|||
|
|
Dim strTag As String
|
|||
|
|
Dim objNode As Node
|
|||
|
|
|
|||
|
|
For i = 1 To SourceNode.Nodes.Count
|
|||
|
|
With SourceNode.Nodes.Item(i)
|
|||
|
|
strText = .Text
|
|||
|
|
strTag = .Tag
|
|||
|
|
End With
|
|||
|
|
objNode = TargetNode.Nodes.Add(strText, strTag)
|
|||
|
|
If Not SourceNode.Nodes.Item(i).Expanded Then
|
|||
|
|
objNode.Collapse()
|
|||
|
|
End If
|
|||
|
|
CopyNode(SourceNode.Nodes.Item(i), objNode)
|
|||
|
|
Next
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
#End Region
|
|||
|
|
#Region "Friend 方法"
|
|||
|
|
|
|||
|
|
Friend Sub UpdateChindrenCount(ByVal diff As Integer)
|
|||
|
|
'更新子节点数
|
|||
|
|
mintChildrenCount = mintChildrenCount + diff
|
|||
|
|
If mobjParent IsNot Nothing Then
|
|||
|
|
mobjParent.UpdateChindrenCount(diff)
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Friend Sub UpdateVisibleNodesCount(ByVal diff As Integer)
|
|||
|
|
'更新可见节点数
|
|||
|
|
mintVisibleNodesCount = mintVisibleNodesCount + diff
|
|||
|
|
If mobjParent IsNot Nothing Then
|
|||
|
|
If mobjParent.Expanded Then
|
|||
|
|
mobjParent.UpdateVisibleNodesCount(diff)
|
|||
|
|
End If
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Friend Function FindNextVisibleNode() As Node
|
|||
|
|
Return FindNextVisibleNode(False)
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
Friend Function FindNextVisibleNode(ByVal FindNext As Boolean) As Node
|
|||
|
|
Dim i As Integer
|
|||
|
|
Dim CollapsedNode As Node = Nothing
|
|||
|
|
|
|||
|
|
'检查所有父节点是否包含Collapsed节点
|
|||
|
|
If mintLevel > 0 Then
|
|||
|
|
Dim tmpNode As Node
|
|||
|
|
tmpNode = mobjParent
|
|||
|
|
For i = mintLevel To 1 Step -1
|
|||
|
|
If Not tmpNode.Expanded Then
|
|||
|
|
CollapsedNode = tmpNode
|
|||
|
|
End If
|
|||
|
|
tmpNode = tmpNode.Parent
|
|||
|
|
Next
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
If CollapsedNode IsNot Nothing Then
|
|||
|
|
Return CollapsedNode.FindNextVisibleNode
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
'FindNext是指要排除自己的子节点,从下一个节点开始搜索
|
|||
|
|
If (Not FindNext) AndAlso mblnExpanded AndAlso mintChildrenCount > 0 Then
|
|||
|
|
Return mobjNodes.FirstNode
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
If mobjNextNode Is Nothing Then
|
|||
|
|
If mobjParent Is Nothing OrElse mintLevel = 1 Then
|
|||
|
|
Return Nothing
|
|||
|
|
Else
|
|||
|
|
Return mobjParent.FindNextVisibleNode(True)
|
|||
|
|
End If
|
|||
|
|
Else
|
|||
|
|
Return mobjNextNode
|
|||
|
|
End If
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
Friend Function FindLastVisibleChildNode() As Node
|
|||
|
|
If mintVisibleNodesCount = 1 Then
|
|||
|
|
Return Me
|
|||
|
|
Else
|
|||
|
|
Return mobjNodes.LastNode.FindLastVisibleChildNode
|
|||
|
|
End If
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
Friend Function FindPrevVisibleNode() As Node
|
|||
|
|
Dim i As Integer
|
|||
|
|
Dim CollapsedNode As Node = Nothing
|
|||
|
|
|
|||
|
|
'检查所有父节点是否包含Collapsed节点
|
|||
|
|
If mintLevel > 0 Then
|
|||
|
|
Dim tmpNode As Node
|
|||
|
|
tmpNode = mobjParent
|
|||
|
|
For i = mintLevel To 1 Step -1
|
|||
|
|
If Not tmpNode.Expanded Then
|
|||
|
|
CollapsedNode = tmpNode
|
|||
|
|
End If
|
|||
|
|
tmpNode = tmpNode.Parent
|
|||
|
|
Next
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
If CollapsedNode IsNot Nothing Then
|
|||
|
|
Return CollapsedNode
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
If mobjPrevNode IsNot Nothing Then
|
|||
|
|
Return mobjPrevNode.FindLastVisibleChildNode
|
|||
|
|
Else
|
|||
|
|
If mobjParent Is Nothing Then
|
|||
|
|
Return Nothing
|
|||
|
|
Else
|
|||
|
|
Return mobjParent
|
|||
|
|
End If
|
|||
|
|
End If
|
|||
|
|
End Function
|
|||
|
|
#End Region
|
|||
|
|
#Region "Public方法"
|
|||
|
|
|
|||
|
|
Public Sub New()
|
|||
|
|
mstrKey = ""
|
|||
|
|
mstrText = ""
|
|||
|
|
mstrTag = ""
|
|||
|
|
mintLevel = 0
|
|||
|
|
mblnExpanded = True
|
|||
|
|
mintChildrenCount = 0
|
|||
|
|
mintVisibleNodesCount = 1
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub New(ByVal Key As String, ByVal Text As String, ByVal Tag As String, ByVal Level As Integer, ByVal Parent As Node)
|
|||
|
|
mstrKey = Key
|
|||
|
|
mstrText = Text
|
|||
|
|
mstrTag = Tag
|
|||
|
|
mintLevel = Level
|
|||
|
|
mobjParent = Parent
|
|||
|
|
mblnExpanded = True
|
|||
|
|
mintChildrenCount = 0
|
|||
|
|
mintVisibleNodesCount = 1
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub Collapse()
|
|||
|
|
If (mintLevel = 0) OrElse (Not mblnExpanded) Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
mblnExpanded = False
|
|||
|
|
UpdateVisibleNodesCount(1 - mintVisibleNodesCount)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub Expand()
|
|||
|
|
If mblnExpanded Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
Dim i As Integer
|
|||
|
|
mblnExpanded = True
|
|||
|
|
If mobjNodes IsNot Nothing Then
|
|||
|
|
For i = 1 To mobjNodes.Count
|
|||
|
|
UpdateVisibleNodesCount(mobjNodes.Item(i).VisibleNodesCount)
|
|||
|
|
Next
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub ExpandAll()
|
|||
|
|
Expand()
|
|||
|
|
|
|||
|
|
Dim i As Integer
|
|||
|
|
If mobjNodes IsNot Nothing Then
|
|||
|
|
For i = 1 To mobjNodes.Count
|
|||
|
|
mobjNodes.Item(i).ExpandAll()
|
|||
|
|
Next
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub LevelUp()
|
|||
|
|
'升级规则:成为父节点的NextNode
|
|||
|
|
If mobjParent.Level = 1 Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
Dim objNode As Node = mobjParent.Parent.Nodes.InsertAfter(mobjParent.Key, mstrText, mstrTag)
|
|||
|
|
CopyNode(Me, objNode)
|
|||
|
|
mobjParent.Nodes.Remove(mstrKey)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub LevelDown()
|
|||
|
|
'降级规则:成为PrevNode的最后一个子节点
|
|||
|
|
If mobjPrevNode Is Nothing Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
Dim objNode As Node = mobjPrevNode.Nodes.Add(mstrText, mstrTag)
|
|||
|
|
CopyNode(Me, objNode)
|
|||
|
|
mobjParent.Nodes.Remove(mstrKey)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub MoveUp()
|
|||
|
|
'上移规则:和PrevNode交换位置
|
|||
|
|
If mobjPrevNode Is Nothing Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
Dim objNode As Node = mobjParent.Nodes.InsertBefore(mobjPrevNode.Key, mstrText, mstrTag)
|
|||
|
|
CopyNode(Me, objNode)
|
|||
|
|
mobjParent.Nodes.Remove(mstrKey)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub MoveDown()
|
|||
|
|
'下移规则:和NextNode交换位置
|
|||
|
|
If mobjNextNode Is Nothing Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
Dim objNode As Node = mobjParent.Nodes.InsertAfter(mobjNextNode.Key, mstrText, mstrTag)
|
|||
|
|
CopyNode(Me, objNode)
|
|||
|
|
mobjParent.Nodes.Remove(mstrKey)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Function FindNode(ByVal Index As Integer) As Node
|
|||
|
|
'根据绝对位置定位Node
|
|||
|
|
If Index = 1 Then
|
|||
|
|
Return Me
|
|||
|
|
End If
|
|||
|
|
Dim i As Integer = Index - 1
|
|||
|
|
If Me.ChildrenCount >= i Then
|
|||
|
|
Return Me.Nodes.FirstNode.FindNode(i)
|
|||
|
|
Else
|
|||
|
|
i = i - Me.ChildrenCount
|
|||
|
|
If Me.NextNode Is Nothing Then
|
|||
|
|
Return Nothing
|
|||
|
|
Else
|
|||
|
|
Return Me.NextNode.FindNode(i)
|
|||
|
|
End If
|
|||
|
|
End If
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
#End Region
|
|||
|
|
|
|||
|
|
End Class
|