treeview 实现多选

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值