שתף באמצעות


TreeView - Expand only selected node and collapse others

Question

Friday, March 13, 2015 6:22 PM

Hi

How I can expand only selected node and collapse other nodes that was expanded earlier?!

All replies (12)

Friday, March 13, 2015 7:03 PM ✅Answered | 2 votes

Hi,

 Using a class scoped TreeNode variable and the TreeView`s BeforeExpand event you can do this.

Public Class Form1
    Dim expanded As TreeNode

    Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
        Dim pn As TreeNode = e.Node
        While pn.Parent IsNot Nothing
            pn = pn.Parent
        End While
        If expanded IsNot Nothing And expanded IsNot pn Then expanded.Collapse()
        expanded = pn
    End Sub
End Class

If you say it can`t be done then i`ll try it


Sunday, March 15, 2015 4:46 PM ✅Answered | 1 vote

Ghostenigma,

switch Option Strict On. I've tried to analyze the code but it's not usable due to type ignorance.

BTW, Goto is not required here. ELSEif means it's only executed if the previous expressions are not true.

Armin

Ignore other code and give an reply for what I've asked else you are not obligated to post a reply at all!

 I am not sure if you took the "type ignorance" part wrong but, Armin was only trying to give you helpful information which i would give too.  Option Strict is a GOOD thing to use and the GoTo statements are not needed inside your ElseIf statements.  As far as that goes, i would not recommend using GoTo in any modern .Net programming.

 Anyways, the problem is with the way you are Adding and Removing all the child nodes every time the nodes are DoubleClicked and when they are Collapsing.  I just simulated your code to add the sub nodes when a main node is double clicked.  You can just use the NodeMouseDoubleClick event instead of the TreeView`s DoubleClick event to make it a little easier on yourself too.

 This corrected the problem for me.

Public Class Form1
    Private r As New Random ' this random class is only for my simulation of adding sub nodes (not needed)
    Private expanded As TreeNode

    Private Sub TreeView1_BeforeCollapse(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeCollapse
        e.Node.Nodes.Clear()
    End Sub

    Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
        Dim pn As TreeNode = e.Node
        While pn.Parent IsNot Nothing
            pn = pn.Parent
        End While
        If expanded IsNot Nothing And expanded IsNot pn Then expanded.Collapse()
        expanded = pn
    End Sub

    Private Sub TreeView1_NodeMouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick

        'Added this part to collapse the prior expanded node and set the (expanded) node to the new one
        If expanded IsNot Nothing And expanded IsNot e.Node Then
            expanded.Collapse()
            Dim pn As TreeNode = e.Node
            While pn.Parent IsNot Nothing
                pn = pn.Parent
            End While
            expanded = pn
        End If

        'This just simulates your code to add the new sub nodes to the main node that was double clicked
        'you need to put your code here instead of this.
        Dim str() As String = {"one.mp3", "Two.mp4", "Three.mvk"}
        Dim s As String = str(r.Next(0, 3))
        e.Node.Nodes.Add(s, s)
        e.Node.Expand()

    End Sub
End Class

 

 PS - I notice you are adding more and more Images to your ImageList every time you double click on a node.  If you just add the Images to it once when the app is loading then you can just use the Image Key to set the correct Image to the newly added node.

If you say it can`t be done then i`ll try it


Friday, March 13, 2015 6:44 PM | 1 vote

You should be able to do something like:

Record the selected node in a local variable.  Call CollapseAll on the TreeView instance.  Call Expand on the local node variable.

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Friday, March 13, 2015 7:03 PM | 1 vote

You should be able to do something like:

Record the selected node in a local variable.  Call CollapseAll on the TreeView instance.  Call Expand on the local node variable.

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

I guess it's a little trickier that... you have to use EnsureVisible as well.  Here's a way using the Before/AfterExpand events that seems to work well enough:

Private expandingNode As TreeNode
Private Sub TreeView1_AfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterExpand
    e.Node.EnsureVisible()
    If Not e.Node.IsExpanded Then
        expandingNode = e.Node
        e.Node.Expand()
    End If
End Sub

Private Sub TreeView1_BeforeExpand(sender As Object, e As TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
    If expandingNode Is Nothing Then TreeView1.CollapseAll()
    expandingNode = Nothing
End Sub

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Friday, March 13, 2015 7:16 PM

IronRazerz perfect!

You don't have to try it because it's working :D

Thanks guys


Friday, March 13, 2015 7:24 PM

IronRazerz perfect!

You don't have to try it because it's working :D

Thanks guys

 You`re Welcome.   8)

 To late, i already tried it even though nobody said it can`t be done.  8D

If you say it can`t be done then i`ll try it


Sunday, March 15, 2015 10:44 AM

Hey Iron after testing my program the example you gave it's only working for the firs time or two times and than it's not working anymore!

So after expanding three or more nodes the other nodes are not being collapsed!

It's working only in the first or second expand?!!

I don't know why?!


Sunday, March 15, 2015 11:27 AM

Hmmm...  I don`t know right off hand what might be happening.  I have been expanding and contracting nodes for a few minutes now trying to get it to not work and it seems to keep working on my end no mater how many or in what order it expand and contract them. However, there has to be something that i am missing that must be happening in your code and not mine.

 Have you noticed if it is certain nodes that it stops working on or is it any nodes?  Perhaps showing the code you use to add or remove any nodes and any code that may alter the nodes in any way may help.  If your code is really large then maybe create a small example code that will reproduce the error and posting that will help.

If you say it can`t be done then i`ll try it


Sunday, March 15, 2015 1:07 PM

I will show you some code

 Private Sub TreeView1_BeforeCollapse(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeCollapse
        e.Node.Nodes.Clear() ' 
    End Sub
    Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
        Dim pn As TreeNode = e.Node
        While pn.Parent IsNot Nothing
            pn = pn.Parent
        End While
        If expanded IsNot Nothing And expanded IsNot pn Then expanded.Collapse()
        expanded = pn
    End Sub

      Double click event on treeview

        Try
            Dim request As FtpWebRequest = FtpWebRequest.Create(webhost + TreeView1.SelectedNode.FullPath + "/")
            request.Credentials = New NetworkCredential(login, password)
            If first = 0 Then
                AddLog(String.Format("Connecting to {0} with {1} - {2}", webhost, login, password))
            End If
            request.Method = WebRequestMethods.Ftp.ListDirectory
            Dim response As FtpWebResponse = request.GetResponse()
            cur_state = response.StatusCode
            AddLog(String.Format("Received code: {0}", response.StatusDescription))
            old_url = request.RequestUri.ToString
            If first = 0 Then
                AddLog(String.Format("WelcomeMessage: {0}", response.WelcomeMessage))
                first = 1
            End If
            Dim sr As New StreamReader(request.GetResponse().GetResponseStream())
            Dim str As String = sr.ReadLine()
            While Not str Is Nothing
                TreeView1.SelectedNode.Nodes.Add(str, str, nIndex, nIndex)
                nIndex = nIndex + 1





                If str.Contains(".mp4") Or str.Contains(".MP4") Or str.Contains(".mvk") Or str.Contains(".mpeg2") Or str.Contains(".mpeg4") Then
                    ImageList1.Images.Add(ico5.ToBitmap)
                    GoTo g



                ElseIf str.Contains(".") Then
                    ImageList1.Images.Add(ico3.ToBitmap)
                    GoTo g

                ElseIf str.Contains(".mp3") Or str.Contains(".m3u") Then
                    ImageList1.Images.Add(ico3.ToBitmap)
                    GoTo g
                Else
                    ImageList1.Images.Add(ico4.ToBitmap)
                End If
g:
                TreeView1.ExpandAll()
                str = sr.ReadLine()
            End While




         

            sr.Close()
            AddLog(String.Format("Connection closed."))
            sr = Nothing
            request = Nothing




        Catch ex As Exception
            MsgBox(ex.Message)
        End Try


Sunday, March 15, 2015 1:49 PM | 1 vote

Ghostenigma,

switch Option Strict On. I've tried to analyze the code but it's not usable due to type ignorance.

BTW, Goto is not required here. ELSEif means it's only executed if the previous expressions are not true.

Armin


Sunday, March 15, 2015 2:03 PM

Ghostenigma,

switch Option Strict On. I've tried to analyze the code but it's not usable due to type ignorance.

BTW, Goto is not required here. ELSEif means it's only executed if the previous expressions are not true.

Armin

Ignore other code and give an reply for what I've asked else you are not obligated to post a reply at all!


Sunday, March 15, 2015 5:09 PM

Problem solved by adding

 If expanded IsNot Nothing And expanded IsNot e.Node Then
            expanded.Collapse()
            Dim pn As TreeNode = e.Node
            While pn.Parent IsNot Nothing
                pn = pn.Parent
            End While
            expanded = pn
        End If

in  TreeView1_NodeMouseDoubleClick

"Armin was only trying to give you helpful information which i would give too"

I do apologise for that.I was a bit upset about the program that was not working.

I do know for what goto and else,elseif are used for.The code posted was just to show an example but not my exact code.

Anyway Thank You

To be exact for others that might find this useful

Added the first code on the mousedoubleclick

so this

    Dim pn As TreeNode = e.Node
        While pn.Parent IsNot Nothing
            pn = pn.Parent
        End While
        If expanded IsNot Nothing And expanded IsNot pn Then expanded.Collapse()
        expanded = pn

and the same code in the Beforeexpandevent

About the images on the imagelist I'm using 

Declare Auto Function ExtractIcon Lib "Shell32" (ByVal spz As Int32, ByVal spathtoextracticonfrom As String, ByVal iconindex As Int32) As IntPtr

to extract windows icons