Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 320
  • Last Modified:

how to show a default path in treeview ?

Hi folks
I thought this would be simple, but I'm foundering.
I am using treeview in VB.NET 2002. I want to have it open so that the default path is expanded, ready for selection by the user. I don't want any other path to be expanded until the user chooses it.
Also, i want to be able to make sure the default path exists, just to prevent errors.
Any suggestions?
thanks
Lifeform23
0
lifeform23
Asked:
lifeform23
  • 14
  • 8
  • 6
1 Solution
 
gdexterCommented:
When you are building your node collection use the Expand method for the node(s) that need to be expanded.

dim n as New TreeNode
With n              
     .Text = "Default"
     .ImageIndex = 11
     .SelectedImageIndex = 11
     .Tag = "ROOT"
     .Expand()
End With
0
 
lifeform23Author Commented:
Thanks for your reply.
I am not clear on how the code you suggest would work.
Why assign a text value when the directory already exists and is named? Since I know the name of the directory I am looking for, can I loop through the existing directories and find the index of the one I want? And assuming I can do that, how do I do it again for the subdirectory? Or am I on the wrong track entirely?
How was the number 11 arrived at in your example?

Perhaps I should make this more concrete and paste in the code I am working with:

  Private Sub Directory_form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Dim oNode As New System.Windows.Forms.TreeNode()
        Dim sDrives() As String = Directory.GetLogicalDrives()
        Dim sDrive As String
        Dim tvRootDrive As New TreeNode()

        Try
            TreeView1.BeginUpdate()
            For Each sDrive In sDrives
                tvRootDrive = New TreeNode(sDrive)
                TreeView1.Nodes.Add(tvRootDrive)
                tvRootDrive.Nodes.Add("")
            Next sDrive
        Catch ex As Exception
            MessageBox.Show("Error listing logical drives" & vbCrLf & ex.Message, "Sorry")
            End
        End Try
        ' now expand the default path
        Try
            ' first set the path to whatever the user has selected or the default path
            If DirectoryName.UserDirectoryPath = "" Then
                DirectoryName.UserDirectoryPath = "C:\first_dir\Second_dir"
            End If
            ' code to expand default path follows:


        Catch ex As Exception
            MsgBox("Cannot list default path" & ex.ToString)
            End
        End Try
        TreeView1.EndUpdate()
        Show()

    End Sub

Any suggestions would be appreciated.
lifeform23
0
 
gdexterCommented:
I am sorry for the brief post on Friday. It was an example just illustrating the Expand method and did not directly apply to your problem.

I most cases you do not want to enumerate the entire folder structure for a drive when loading the treeview. Usually you would use the TreeView_BeforeExpand  event to begin processing the children of the node selected. You would then use a recursive mehod to enumerate the children.

The key here is to be efficient when loading. Here is what I came up with.
 
Add the following to the top of your class
-------------------------------------------------------------------------------------------

Imports System.Text.RegularExpressions


   Private Sub LoadTreeview()

        Dim sDrives() As String = Directory.GetLogicalDrives()
        Dim sDrive As String
        Dim tvRootDrive As TreeNode
        Dim di As DirectoryInfo

        Try
            Dim usersDirectory As String = "C:\MCMS\EST"
            di = New DirectoryInfo(usersDirectory)

            TreeView1.BeginUpdate()
            For Each sDrive In sDrives
                tvRootDrive = New TreeNode(sDrive)
                tvRootDrive.Nodes.Add("")
                Me.TreeView1.Nodes.Add(tvRootDrive)

                'handles selecting the default node
                If (sDrive = di.Root.Name) Then
                    tvRootDrive.Nodes(0).Remove()
                    Me.SelectDefault(tvRootDrive, di, 0)
                    tvRootDrive.Expand()
                End If

            Next sDrive

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try


    End Sub


    Private Sub SelectDefault(ByVal parentNode As TreeNode, ByVal usrDi As DirectoryInfo, ByVal count As Integer)

        Dim di As DirectoryInfo
        Dim d As DirectoryInfo
        Dim nodeX As TreeNode

        'recursive method will call itself until no more directories are found by the srchPattern
        Try
            di = New DirectoryInfo(parentNode.FullPath)
            'get the search pattern to pass to the GetDirectories method
            Dim srchPattern As String = Me.GetPattern(usrDi, count)

            If (srchPattern <> vbNullString) Then
                For Each d In di.GetDirectories(srchPattern)
                    nodeX = New TreeNode(d.Name)
                    parentNode.Nodes.Add(nodeX)
                    nodeX.Expand()
                    count += 1
                    Me.SelectDefault(nodeX, usrDi, count)
                Next
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try

    End Sub


    Private Function GetPattern(ByVal di As DirectoryInfo, ByVal count As Integer) As String

        Dim mtch As Match
        Dim grp As Group
        Dim val As String = vbNullString

        Dim pattern As String = "(\w+\\)+"

        Dim regX As New Regex(pattern)
        mtch = regX.Match(di.FullName & "\")
        grp = mtch.Groups(1)

        Try
            If Not (count > grp.Captures.Count - 1) Then
                val = grp.Captures.Item(count).Value
            End If

        Catch ax As ArgumentOutOfRangeException
            'do nothing
        End Try

        Return Replace(val, "\", "")

    End Function
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
gdexterCommented:
In the example I provided I gave a limited matching pattern for the RegX option. The pattern below allows for more charachters that may be found in a folder name.

Dim pattern As String = "([a-zA-Z_0-9\-\.]+\\)+"

You may want to expand this pattern for you implementation
0
 
wguerramCommented:
Actually there is no way to get an specific node.

You have to add a Tag attribute to the node you want to be expanded and loop for all the nodes until you get the node with attribute.

Or if you are using Unique path you know the default path you can loop through all nodes until you find the node and then

call the expand method.

0
 
wguerramCommented:
Check this in order to find a node by key:

http://support.microsoft.com/default.aspx?scid=kb;en-us;311318
0
 
lifeform23Author Commented:
gdexter
Thank you for taking the time to post such a complete section of code.
As I try to type it in, the IDE rejects the line
Me.SelectDefault(tvRootDrive, di, 0)
There is no ".selectdefault" command available, simply ".select", and it doesn't accept parameters.
I am not sure how to work around this. Any suggestions would be welcome.
Thanks
lifeform23
0
 
gdexterCommented:
hmm...
Try pasting the entire methods:
Private Sub SelectDefault(....)
Private Function GetPattern(...)
that I provided into your forms class. Then add the LoadTreeview Sub

0
 
gdexterCommented:
Did you ever get this to work?
0
 
lifeform23Author Commented:
Not yet.
I was able to load the subroutines properly and call the selectdefault subroutine.
When I ran your code as is, the box listed all the logical drives, but unexpanded. It also left the "+" sign off the "C:\" drive, which has the default sequence on it, so the user could not expand it.
When I deleted the line "tvRootDrive.Nodes(0).Remove()", things improved.
The box opens with all the first level folders on the default drive listed. However my default is a second level folder (e.g., "C:\1stlevel\2ndlevel\"), so I will have to spend some time trying to puzzle out how to move down a level to open the default folder. I am sure the answer is in the code you and wguerram have suggested, but I need to get the time to dig through it and sort it out. Perhaps this weekend...
Thanks for your help.
lifeform23

0
 
gdexterCommented:
Make sure your are using this pattern variable in GetPattern Function

Dim pattern As String = "([a-zA-Z_0-9\-\.]+\\)+"
0
 
gdexterCommented:
Post you load method so I can look at the problem when you have a chance.
0
 
wguerramCommented:
Private Sub Directory_form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load        
        'I tried looking for this path
        Dim strPath As String = "Node1\Node5\Node6"

        If Not ExpandNode(Me.TreeView1.Nodes(0), strPath) Then
            MsgBox("Cannot list default path")
        End If
End Sub

'This function expand the default path, just send the first node of the treeview as a parameter
Private Function ExpandNode(ByVal FirstNode As TreeNode, ByVal NodePath As String) As Boolean
        Dim _TreeNode As TreeNode
        Dim blnFound As Boolean

        _TreeNode = FirstNode
        Do While Not _TreeNode Is Nothing
            If _TreeNode.FullPath = NodePath Then
                _TreeNode.EnsureVisible()
                blnFound = True
                Exit Do
            Else
                If _TreeNode.GetNodeCount(False) > 0 Then
                    blnFound = ExpandNode(_TreeNode.FirstNode, NodePath)
                    If blnFound Then
                        Exit Do
                    End If
                End If
            End If
            _TreeNode = _TreeNode.NextNode
        Loop

        _TreeNode = Nothing

        Return blnFound
    End Function
0
 
wguerramCommented:
Modify this in order to make comparison with lower cases in order to be case insensitive.        

           If _TreeNode.FullPath.ToLower = NodePath.ToLower Then
                _TreeNode.EnsureVisible()
                blnFound = True
                Exit Do
            Else
                If _TreeNode.GetNodeCount(False) > 0 Then
                    blnFound = ExpandNode(_TreeNode.FirstNode, NodePath)
                    If blnFound Then
                        Exit Do
                    End If
                End If
            End If
0
 
gdexterCommented:
wguerram,

Remember he is dealing with the file system.

The problem with your code is that he would have to load the entire directory structure in the Treeview for this to work. That would be very in-efficient.
0
 
wguerramCommented:
'Just the fact to add all directories to a treeview is very slow.


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Dim oNode As New System.Windows.Forms.TreeNode()
        Dim sDrives() As String = Directory.GetLogicalDrives()

        Dim sDrive As String
        Dim tvRootDrive As New TreeNode()

        Dim strPath As String = "C:\asprk\Additional Resources\Case Studies"


        Try
            TreeView1.BeginUpdate()
            For Each sDrive In sDrives
                tvRootDrive = New TreeNode(sDrive)
                TreeView1.Nodes.Add(tvRootDrive)

                Replace(strPath, "\", "\\", 1, 1)

                LoadDirectories(tvRootDrive, "C:\\asprk\Additional Resources\Case Studies", 1)
            Next sDrive
        Catch ex As Exception
            MessageBox.Show("Error listing logical drives" & vbCrLf & ex.Message, "Sorry")
            End
        End Try

        ' now expand the default path
        Try
            ' first set the path to whatever the user has selected or the default path
            'If DirectoryName.UserDirectoryPath = "" Then
            'DirectoryName.UserDirectoryPath = "C:\first_dir\Second_dir"
            'End If
            ' code to expand default path follows:


        Catch ex As Exception
            MsgBox("Cannot list default path" & ex.ToString)
            End
        End Try
        TreeView1.EndUpdate()

    End Sub

'This methos adds the directory to the treeview and also expand the default directory
'I added a level variable just to see the directories show soon, since there are alot of directories

Private Sub LoadDirectories(ByVal RootNode As TreeNode, ByVal DefaultPath As String, ByVal Level As Integer)
        ' Make a reference to a directory.
        Dim di As DirectoryInfo
        ' Get a reference to each directory in that directory.
        Dim diArr As DirectoryInfo()

        ' Display the names of the directories.
        Dim dri As DirectoryInfo

        Dim NewNode As TreeNode

        di = New DirectoryInfo(RootNode.FullPath)
        Try
            diArr = di.GetDirectories()
        Catch
        End Try

        If Not IsNothing(diArr) Then
            For Each dri In diArr
                NewNode = RootNode.Nodes.Add(dri.Name)
                If NewNode.FullPath.ToLower = DefaultPath.ToLower Then
                    NewNode.EnsureVisible()                    
                End If
                Level += 1
                If Level <= 4 Then
                    LoadDirectories(NewNode, DefaultPath, 1)
                End If
            Next dri


        End If
    End Sub
0
 
gdexterCommented:
Exactly,
The code I posted only searches for the actual default directories required and it works (I tested it on numerous directory paths).
You can then handle opening the other nodes(drives,folders) through the Treeview_BeforeExpand Event. I would never recommend loading the entire folder structure all oat once for an application.
0
 
gdexterCommented:
Here is an updated version that i think will do the trick.

    Private Sub LoadTreeview()

        Dim sDrives() As String = Directory.GetLogicalDrives()
        Dim sDrive As String
        Dim tvRootDrive As TreeNode
        Dim di As DirectoryInfo

        Try
            Dim usersDirectory As String = "P:\gis\PRG\SHA"
            di = New DirectoryInfo(usersDirectory)

            TreeView1.BeginUpdate()
            For Each sDrive In sDrives
                Dim fmtDrv As String = Replace(sDrive, "\", "")
                tvRootDrive = New TreeNode(fmtDrv)
                tvRootDrive.Nodes.Add("")
                Me.TreeView1.Nodes.Add(tvRootDrive)

                'handles selecting the default node
                If (sDrive = di.Root.Name) Then
                    Me.EnumerateChildren(tvRootDrive)
                    tvRootDrive.Nodes(0).Remove()
                    Me.SelectDefault(tvRootDrive, di, 0)
                    tvRootDrive.Expand()
                End If

            Next sDrive

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try


    End Sub

    Private Sub EnumerateChildren(ByVal oParent As System.Windows.Forms.TreeNode)

        Dim oFS As DirectoryInfo
        Dim oDir As DirectoryInfo
        Dim path As String

        oFS = New DirectoryInfo(oParent.FullPath)

        Try
            For Each oDir In oFS.GetDirectories()
                Dim oNode As New System.Windows.Forms.TreeNode
                oNode.Text = oDir.Name
                oParent.Nodes.Add(oNode)
                oNode.Nodes.Add("")
            Next

        Catch ex As Exception
            MessageBox.Show("Cannot list folders of ", oParent.Text)

        End Try

    End Sub

    Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object, _
                                       ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand

        Try
            If (e.Node.GetNodeCount(False) = 1 And e.Node.Nodes(0).Text = "") Then
                e.Node.Nodes(0).Remove()
                Me.EnumerateChildren(e.Node)
            End If

        Catch ex As Exception
            MessageBox.Show("Unable to expand ", e.Node.FullPath)

        End Try

    End Sub

    Private Sub SelectDefault(ByVal parentNode As TreeNode, ByVal usrDi As DirectoryInfo, ByVal count As Integer)

        Dim di As DirectoryInfo
        Dim d As DirectoryInfo
        Dim nodeX As TreeNode

        Try
            di = New DirectoryInfo(parentNode.FullPath)
            Dim srchPattern As String = Me.GetPattern(usrDi, count)

            If (srchPattern <> vbNullString) Then
                For Each d In di.GetDirectories(srchPattern)
                    nodeX = New TreeNode(d.Name)
                    parentNode.Nodes.Add(nodeX)
                    nodeX.Nodes.Add("")
                    nodeX.Expand()
                    Me.EnumerateChildren(nodeX)
                    nodeX.Nodes(0).Remove()
                    count += 1
                    Me.SelectDefault(nodeX, usrDi, count)
                Next
            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try

    End Sub

    Private Function GetPattern(ByVal di As DirectoryInfo, ByVal count As Integer) As String

        Dim mtch As Match
        Dim cpts As CaptureCollection
        Dim cpt As Capture
        Dim grp As Group
        Dim val As String = vbNullString

        Dim pattern As String = "([a-zA-Z_0-9\-\.\s]+\\)+"

        Dim regX As New Regex(pattern)
        mtch = regX.Match(di.FullName & "\")
        grp = mtch.Groups(1)

        Try
            If Not (count > grp.Captures.Count - 1) Then
                val = grp.Captures.Item(count).Value
            End If

        Catch ax As ArgumentOutOfRangeException
            'do nothing
        End Try

        Return Replace(val, "\", "")

    End Function

'Paste all of the methods and call LoadTreeView from your form
'Adjust the usersDirectory variable as needed and change the TreeView name to the one on your form
0
 
lifeform23Author Commented:
Thank you for the new code. I had spent some time with the previous version you had suggested, but found it produced blank (unnamed) directories, and duplicate entries, and produced different results the second time one opened a directory window than it had the first time. I spent some time trying to fix it by trial and error, but really just added a new bug or two for every one I removed.
So, working with the latest code I found there is a missing statement Treeview1.endupdate()  at the end of LoadTreeView.
Once I put that in, the directory listed is nodes only, and the C: node (which is the root of the default path) is lacking a plus sign and cannot be expanded. So I will start tinkering with it a bit and see what I can do with it.
I really wasn't expecting that setting a directory would be so complex.
Thanks for your help.
Lifeform23
0
 
lifeform23Author Commented:
Hi
I have also found in the moist recent code posted that in the EnumerateChildren subroutine, the line
For Each oDir In oFS.GetDirectories()
finds no subdirectories, although they are present.
lifeform23
0
 
gdexterCommented:
Hello again,

I have went back to thr drawing board and tried to come up with a solution that would correct the problems you were seeing. I am sorry about the earlier posts I did not have adequate time to perform the testing but I have tested this new approach on network and local drives and it seems to work for me. This was driving me crazy as well...

First you will need to declare a form level variable:

   Private IsLoading As Boolean            'this represents a flag set during the initial load to suppress the expand event
                                                        'essentially prevents doubles in the treevview during load

Second remove all of the methods that I provided in previous posts. and replace with the code below

  Private Sub LoadTreeview()

        Dim sDrives() As String = Directory.GetLogicalDrives()
        Dim sDrive As String
        Dim tvRootDrive As TreeNode
        Dim di As DirectoryInfo

        Try
            Dim usersDirectory As String = "C:\Documents and Settings\Default User"
            di = New DirectoryInfo(usersDirectory)

            Me.TreeView1.BeginUpdate()
            Me.IsLoading = True
            For Each sDrive In sDrives
                'Dim fmtDrv As String = Replace(sDrive, "\", "")
                tvRootDrive = New TreeNode(sDrive)
                tvRootDrive.Nodes.Add("")
                Me.TreeView1.Nodes.Add(tvRootDrive)

                'handles selecting the default node
                If (sDrive = di.Root.Name) Then
                    Me.EnumerateChildren(tvRootDrive)
                    tvRootDrive.Nodes(0).Remove()
                    Me.EnumerateChildren(tvRootDrive, di)
                    tvRootDrive.Expand()
                End If

            Next sDrive
            Me.TreeView1.Sorted = True
            Me.IsLoading = False
            Me.TreeView1.EndUpdate()

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try


    End Sub

    Private Overloads Sub EnumerateChildren(ByVal oParent As System.Windows.Forms.TreeNode, ByVal di As DirectoryInfo)

        Dim oFS As DirectoryInfo
        Dim oDir As DirectoryInfo
        Dim path As String
        Dim defaultPath() As String
        Dim i As Integer

        path = Replace(oParent.FullPath, "\\", "\")
        oFS = New DirectoryInfo(path)
        defaultPath = Split(di.FullName, "\")

        Try
            For Each oDir In oFS.GetDirectories()
                Dim oNode As New System.Windows.Forms.TreeNode

                oNode.Text = oDir.Name
                oParent.Nodes.Add(oNode)
                oNode.Nodes.Add("")
                For i = 0 To defaultPath.GetUpperBound(0)
                    If (defaultPath(i) = oDir.Name) Then
                        oNode.Expand()
                        oNode.EnsureVisible()
                        Me.EnumerateChildren(oNode, di)
                    End If
                Next
            Next

        Catch ux As UnauthorizedAccessException
            'do nothing

        Catch ex As Exception
            MessageBox.Show("Cannot list folders of ", oParent.Text)

        End Try


    End Sub

    Private Overloads Sub EnumerateChildren(ByVal oParent As System.Windows.Forms.TreeNode)

        Dim oFS As DirectoryInfo
        Dim oDir As DirectoryInfo
        Dim path As String

        Try
            If Not (Me.IsLoading) Then
                path = Replace(oParent.FullPath, "\\", "\")
                oFS = New DirectoryInfo(path)

                For Each oDir In oFS.GetDirectories()
                    Dim oNode As New System.Windows.Forms.TreeNode
                    oNode.Text = oDir.Name
                    oParent.Nodes.Add(oNode)
                    oNode.Nodes.Add("")
                Next
            End If

        Catch ux As UnauthorizedAccessException
            'do nothing

        Catch ex As Exception
            MessageBox.Show("Cannot list folders of ", oParent.Text)

        End Try

    End Sub

    Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object, _
                                       ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand

        Try
            If (e.Node.GetNodeCount(False) = 1 And e.Node.Nodes(0).Text = "") Then
                e.Node.Nodes(0).Remove()
                Me.EnumerateChildren(e.Node)
            End If

        Catch ex As Exception
            MessageBox.Show("Unable to expand ", e.Node.FullPath)

        End Try

    End Sub

Call the LoadTreeView and let me know what happens
                       
0
 
lifeform23Author Commented:
Here are some notes as i try to get the code working. At present I have it working but it is inelegant.

In the Enumerate Children subroutine, I changed the line
oFS = New DirectoryInfo(oParent.FullPath & "\")
by adding in the ‘& "\"’ at the end.  As a result all the first level folder names are displayed, in the order of their creation (not alphabetically), with “+” signs to permit expansion.

When I step through the execution of the SelectDefault subroutine, the same problem occurs as above. The loop does not find any subfolders, although there are subfolders to be found. So I made the same change, adding in ‘& "\" ‘ to the end of the line di = New DirectoryInfo(parentNode.FullPath & "\").

The result is that after the enumeration of the first level directories the default first level directory is listed again, and expanded so that all the directories in it are listed twice, and then the third level directory in it is listed once, with a plus sign. There is a fourth level directory, which is not displayed.

I.e., it shows (after all the other first level folders are listed)
+ First level
+ First level
      + test folder 2
      + a test folder
      + Second level
      + test folder 2
      + a test folder
      - Second level
            + Third level

To stop some of the duplication, I deleted a couple of references to the Enumerate Children subroutine.  This also solves the problem that the folders I wanted came up at the end of a long list of folders and hence out of view in the window.  

The problem left is that the final folder added to treeview doesn’t have a plus sign, even though it has subfolders. Solving this seems like a tricky problem. I added an ugly hack, where I delete the .remove statement from the SelectDefault Subroutine and simply skip writing the node I know is duplicated. It doesn’t work if I change the name of the duplicated default folder or the number of layers deep the default folder lies.

Also, I will need to figure out how the user can get the full enumeration if they close up the root folder and click on the desired drive.

The SelectDefault subroutine duplicates writing some of the nodes that EnumerateChildren writes.

Here is the actual code:
 Private Sub Directory_form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' routine loads the form which displays the treeview and handles directory choice
        LoadTreeview()
    End Sub
    ' ********************************************************************
    Private Sub LoadTreeview()

        Dim sDrives() As String = Directory.GetLogicalDrives()
        Dim sDrive As String
        Dim tvRootDrive As TreeNode
        Dim di As DirectoryInfo

        Try
            ' first set the path to whatever the user has selected or the default path
            If DirectoryName.UserDirectoryPath = "" Then
                DirectoryName.UserDirectoryPath = "C:\First Level\Second Level\"
            End If

            Dim usersDirectory As String = DirectoryName.UserDirectoryPath

            di = New DirectoryInfo(usersDirectory)

            TreeView1.BeginUpdate()
            For Each sDrive In sDrives
                Dim fmtDrv As String = Replace(sDrive, "\", "")
                tvRootDrive = New TreeNode(fmtDrv)
                tvRootDrive.Nodes.Add("")
                Me.TreeView1.Nodes.Add(tvRootDrive)

                'handles selecting the default node
                If (sDrive = di.Root.Name) Then
                    ' list all the first level folders - don't want them - screen too crowded, and the one we want is listed last and out of the window
                    '   Me.EnumerateChildren(tvRootDrive)
                    ' without the next line a blank extra node appears
                    tvRootDrive.Nodes(0).Remove()
                    Me.SelectDefault(tvRootDrive, di, 0)
                    tvRootDrive.Expand()
                End If

            Next sDrive

        Catch ex As Exception
            MessageBox.Show("Error loading directory " & vbCrLf & ex.Message)

        End Try

        TreeView1.EndUpdate()

    End Sub ' LoadTreeview()
    ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    Private Sub EnumerateChildren(ByVal oParent As System.Windows.Forms.TreeNode)

        Dim oFS As DirectoryInfo
        Dim oDir As DirectoryInfo
        Dim path As String

        oFS = New DirectoryInfo(oParent.FullPath & "\")

        Try
            For Each oDir In oFS.GetDirectories()
                Dim oNode As New System.Windows.Forms.TreeNode()
                oNode.Text = oDir.Name
                oParent.Nodes.Add(oNode)
                oNode.Nodes.Add("")
            Next

        Catch ex As Exception
            MessageBox.Show("Cannot list folders of ", oParent.Text)

        End Try

    End Sub ' Enumerate Children
    ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    Private Sub TreeView1_BeforeExpand(ByVal sender As System.Object, _
                                       ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand

        Try
            If (e.Node.GetNodeCount(False) = 1 And e.Node.Nodes(0).Text = "") Then
                e.Node.Nodes(0).Remove()
                Me.EnumerateChildren(e.Node)
            End If

        Catch ex As Exception
            MessageBox.Show("Unable to expand ", e.Node.FullPath)

        End Try

    End Sub ' TreeView1_BeforeExpand
    ' \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    Private Sub SelectDefault(ByVal parentNode As TreeNode, ByVal usrDi As DirectoryInfo, ByVal count As Integer)

        Dim di As DirectoryInfo
        Dim d As DirectoryInfo
        Dim nodeX As TreeNode

        Try
            ' isolates a bug that comes here - arose when I added the code to keep the second level from writing twice -  when the program skips writing it and next passes here it gets a message- I guess it is trying to go one ply down on a non-existent node
            di = New DirectoryInfo(parentNode.FullPath & "\")

        Catch
        End Try
        Try

            Dim srchPattern As String = Me.GetPattern(usrDi, count)

            If (srchPattern <> vbNullString) Then
                For Each d In di.GetDirectories(srchPattern)
                    nodeX = New TreeNode(d.Name)
                    ' next bit keeps the default folder from being added to treeview twice
                    If Not (d.Name = "Second Level") Then
                        parentNode.Nodes.Add(nodeX)
                        nodeX.Nodes.Add("")
                        nodeX.Expand()
                    End If
                    ' Me.EnumerateChildren(nodeX)
                    ' with the next line the Second level repeats and in the second rep adds the third level (without a plus sign)
                    ' nodeX.Nodes(0).Remove()
                    count += 1
                    Me.SelectDefault(nodeX, usrDi, count)

                Next

            End If

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try

    End Sub ' SelectDefault


0
 
gdexterCommented:
Do not use the SelectDefault method. I rewrote the entire routine in my last post using two overloaded Methods EnumerateChildren. Use the code I posted yesterday it worked for me.
0
 
lifeform23Author Commented:
Hi
I tried your last routine this morning. it is simple and elegant. it lists the nodes but doesn not open the default directory. When I step through , the program detects the directories and steps throughthe lines in the enumeratechildren subroutine just fine. It just doesn't add then to the tree and open them.
Thanks for trying.
lifeform23
0
 
lifeform23Author Commented:
I should clarify the previous message. The program lists the logical drives but no directories unless further expanded by the user.
It is really mystifying to me why the program reaches the instruction to expand the nodes and does not expand them.  The IsExpanded value remains false. The next line is EnsureVisible, and the IsVisible parameter of the node stays false as well.
I can't see any material difference to the previous code which expanded the nodes just fine.
 lifeform23
0
 
gdexterCommented:
That is strange because it works for me. Check your node path seperator and make sure that the varaible name is correct.
In the example I provided it was 'IsLoading'
0
 
gdexterCommented:
Could you post the code that you are using again...
0
 
wguerramCommented:
'Check this code:

'This does what you need and is very faster since it loads the folders when the node is expanded the first time.

'It search for a default path to show it if found.

'It's an easy to understand and a very good aproach.

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Dim oNode As New System.Windows.Forms.TreeNode()
        Dim sDrives() As String = System.IO.Directory.GetLogicalDrives()

        Dim sDrive As String
        Dim tvRootDrive As New TreeNode

        Dim strPath As String = "C:\temp" 'Path to search

        TreeView1.BeginUpdate()
        'Fill drive letters
        Try
            For Each sDrive In sDrives                
                tvRootDrive = New TreeNode(sDrive)
                TreeView1.Nodes.Add(tvRootDrive)
                tvRootDrive.Nodes.Add("?")
            Next sDrive
        Catch ex As Exception
            MessageBox.Show("Error listing logical drives" & vbCrLf & ex.Message, "Sorry")
            End
        End Try

        ' now expand the default path
        If Not ExpandNode(Me.TreeView1.Nodes(0), strPath) Then
            MsgBox("Cannot list default path: " & strPath)
        End If        

        TreeView1.EndUpdate() 'Draw treeview
        'Make visible the selected node
        If Not IsNothing(TreeView1.SelectedNode) Then
            TreeView1.SelectedNode.EnsureVisible()
        End If
    End Sub

    Private Sub TreeView1_BeforeExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
        'Check if it is the first time the node will be expanded in order to add dirs
        If e.Node.Nodes(0).Text = "?" Then
            Me.AddDirs(e.Node)
        End If
    End Sub

    'Method to add dirs to the treeview selected node
    Private Sub AddDirs(ByVal node As TreeNode)
        ' Make a reference to a directory.
        Dim di As System.IO.DirectoryInfo

        ' Display the names of the directories.
        Dim dri As System.IO.DirectoryInfo
        Dim NewNode As TreeNode

        node.Nodes.Clear()
        di = New System.IO.DirectoryInfo(node.FullPath)

        For Each dri In di.GetDirectories()
            NewNode = node.Nodes.Add(dri.Name)
            NewNode.Nodes.Add("?") ' This is needed to check if the node already have dirs
        Next dri

        di = Nothing
    End Sub

    'This function expand the default path, just send the first node of the treeview as a parameter
    Private Function ExpandNode(ByVal FirstNode As TreeNode, ByVal NodePath As String) As Boolean
        Dim _TreeNode As TreeNode
        Dim blnFound As Boolean
        Dim strFullpath As String

        _TreeNode = FirstNode
        Do While Not _TreeNode Is Nothing
            strFullpath = Replace(_TreeNode.FullPath, "\\", "\", , 1)
            'If the first characters od the path match
            If InStr(NodePath, strFullpath) = 1 Then
                'Check if they are equal, if so node found
                If NodePath = strFullpath Then
                    _TreeNode.TreeView.SelectedNode = _TreeNode
                    blnFound = True
                Else ' otherwise continue searching
                    Me.AddDirs(_TreeNode)
                    blnFound = ExpandNode(_TreeNode.FirstNode, NodePath)
                End If

                If blnFound Then Exit Do
            End If

            _TreeNode = _TreeNode.NextNode
        Loop

        _TreeNode = Nothing

        Return blnFound
    End Function
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 14
  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now