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
|
||
Public IsDirectory As Boolean = False
|
||
#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
|