treeview 本身不像listview里可以自带多选功能,它是没有的,因此要实现treeview里的多选功能,需要自己来写一个multitreeview 继承类来实现。
代码如下:
Public Class MultiTreeView
Inherits System.Windows.Forms.TreeView
Private lastNode As System.Windows.Forms.TreeNode
Private firstNode As System.Windows.Forms.TreeNode
Private selectedNodes As ArrayList
Public Property SelectedNodesList() As ArrayList
Get
Return selectedNodes
End Get
Set(ByVal Value As ArrayList)
DeselectNodes()
selectedNodes.Clear()
selectedNodes = Value
SelectNodes()
End Set
End Property
Public Function clear()
selectedNodes.Clear()
End Function
Private Function CheckIfParent(ByVal parentNode As System.Windows.Forms.TreeNode, ByVal childNode As System.Windows.Forms.TreeNode) As Boolean
If parentNode Is childNode Then
Return True
End If
Dim node As System.Windows.Forms.TreeNode = childNode
Dim parentFound As Boolean = False
While (Not parentFound And Not (node Is Nothing))
node = node.Parent
parentFound = (node Is parentNode)
End While
Return parentFound
End Function
Private Sub SelectNodes()
Dim n As System.Windows.Forms.TreeNode
For Each n In selectedNodes
n.BackColor = System.Drawing.SystemColors.Highlight
n.ForeColor = System.Drawing.SystemColors.HighlightText
Next
End Sub
Private Sub DeselectNodes()
If selectedNodes Is Nothing Then
Exit Sub
End If
If selectedNodes.Count = 0 Then
Exit Sub
End If
Dim backColor As System.Drawing.Color = Me.BackColor()
Dim foreColor As System.Drawing.Color = Me.ForeColor()
Dim n As System.Windows.Forms.TreeNode
For Each n In selectedNodes
n.ForeColor = foreColor
n.BackColor = backColor
Next
End Sub
Private Sub SelectAllNodes(ByVal nodes As System.Windows.Forms.TreeNodeCollection)
Dim n As System.Windows.Forms.TreeNode
For Each n In Me.Nodes
selectedNodes.Add(n)
If (n.Nodes.Count > 1) Then
SelectAllNodesInNode(n.Nodes, n)
End If
Next
SelectNodes()
End Sub
Private Sub SelectAllNodesInNode(ByVal nodes As System.Windows.Forms.TreeNodeCollection, ByVal node As System.Windows.Forms.TreeNode)
Dim n As System.Windows.Forms.TreeNode
For Each n In node.Nodes
selectedNodes.Add(n)
If (n.Nodes.Count > 1) Then
SelectAllNodesInNode(n.Nodes, n)
End If
Next
SelectNodes()
End Sub
Protected Overrides Sub OnKeyUp(ByVal e As System.Windows.Forms.KeyEventArgs)
MyBase.OnKeyDown(e)
Dim Pressed As Boolean = (e.Control And ((e.KeyData & System.Windows.Forms.Keys.A) = (System.Windows.Forms.Keys.A)))
If (Pressed) Then
SelectAllNodes(Me.Nodes)
End If
End Sub
Public Sub New()
selectedNodes = New ArrayList
End Sub
Protected Overrides Sub OnBeforeSelect(ByVal e As System.Windows.Forms.TreeViewCancelEventArgs)
MyBase.OnBeforeSelect(e)
'Check for the current keys press..
Dim isControlPressed As Boolean = (ModifierKeys = System.Windows.Forms.Keys.Control)
Dim isShiftPressed As Boolean = (ModifierKeys = System.Windows.Forms.Keys.Shift)
'If control is pressed and the selectedNodes contains current Node
'Deselect that node...
'/Remove from the selectedNodes Collection...
If (isControlPressed And selectedNodes.Contains(e.Node)) Then
DeselectNodes()
selectedNodes.Remove(e.Node)
SelectNodes()
'MultiSelectTreeView has handled this event ....
'Windows.Forms.TreeView should eat this event.
e.Cancel = True
Return
End If
'else (if Shift key is pressed)
'Start the multiselection ...
'Since Shift is pressed we would "SELECT"
'all nodes from first node - to last node
lastNode = e.Node
'If Shift not pressed...
'Remember this Node to be the Sart Node .. in case user presses Shift to
'select multiple nodes.
If (Not isShiftPressed) Then
firstNode = e.Node
End If
End Sub
Protected Overrides Sub OnAfterSelect(ByVal e As System.Windows.Forms.TreeViewEventArgs)
MyBase.OnAfterSelect(e)
'Check for the current keys press..
Dim isControlPressed As Boolean = (ModifierKeys = System.Windows.Forms.Keys.Control)
Dim isShiftPressed As Boolean = (ModifierKeys = System.Windows.Forms.Keys.Shift)
If (isControlPressed) Then
If (Not selectedNodes.Contains(e.Node)) Then
'This is a new Node, so add it to the list.
selectedNodes.Add(e.Node)
Else
'If control is pressed and the selectedNodes contains current Node
'//Deselect that node...
'//Remove from the selectedNodes Collection...
DeselectNodes()
selectedNodes.Remove(e.Node)
End If
SelectNodes()
Else
' SHIFT is pressed
If isShiftPressed Then
'Start Looking for the start and end nodes to select all the nodes between them.
Dim uppernode As System.Windows.Forms.TreeNode = firstNode
Dim bottomnode As System.Windows.Forms.TreeNode = e.Node
'//Check Parenting Upper ---> Bottom
'//Is Upper Node parent (direct or indirect) of Bottom Node
Dim bParent As Boolean = CheckIfParent(uppernode, bottomnode)
If (Not bParent) Then
'//Check Parenting the other way round
bParent = CheckIfParent(bottomnode, uppernode)
If (bParent) Then
Dim temp As System.Windows.Forms.TreeNode = uppernode
uppernode = bottomnode
bottomnode = temp
End If
End If
If (bParent) Then
Dim n As System.Windows.Forms.TreeNode = bottomnode
While (Not (n Is uppernode.Parent))
If (Not selectedNodes.Contains(n)) Then
selectedNodes.Add(n)
End If
n = n.Parent
End While
'// Parenting Fails ... but check if the NODES are on the same LEVEL.
Else
If ((uppernode.Parent Is Nothing And bottomnode.Parent Is Nothing) Or (Not (uppernode.Parent Is Nothing) And uppernode.Parent.Nodes.Contains(bottomnode))) Then '// are they siblings ?
Dim nIndexUpper As Integer = uppernode.Index
Dim nIndexBottom As Integer = bottomnode.Index
'//Need to SWAP if the order is reversed...
If (nIndexBottom < nIndexUpper) Then
Dim temp As System.Windows.Forms.TreeNode = uppernode
uppernode = bottomnode
bottomnode = temp
nIndexUpper = uppernode.Index
nIndexBottom = bottomnode.Index
End If
Dim n As System.Windows.Forms.TreeNode = uppernode
selectedNodes.Clear()
While (nIndexUpper < nIndexBottom)
' //Add all the nodes if nodes not present in the current
'//SelectedNodes list...
If (Not selectedNodes.Contains(n)) Then
selectedNodes.Add(n)
SelectAllNodesInNode(n.Nodes, n)
End If
n = n.NextNode
nIndexUpper += 1
End While
' //Add the Last Node.
selectedNodes.Add(n)
Else
If (Not selectedNodes.Contains(uppernode)) Then
selectedNodes.Add(uppernode)
End If
If (Not selectedNodes.Contains(bottomnode)) Then
selectedNodes.Add(bottomnode)
End If
End If
End If
SelectNodes()
' //Reset the firstNode counter for subsequent "SHIFT" keys.
firstNode = e.Node
Else
'// If Normal selection then add this to SelectedNodes Collection.
If (Not (selectedNodes Is Nothing) And selectedNodes.Count > 0) Then
DeselectNodes()
selectedNodes.Clear()
End If
selectedNodes.Add(e.Node)
End If
End If
End Sub
Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
MyBase.OnGotFocus(e)
SelectNodes()
End Sub
Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)
MyBase.OnLostFocus(e)
DeselectNodes()
End Sub
End Class