Solved

how to show a default path in treeview ?

Posted on 2004-08-27
29
284 Views
Last Modified: 2010-04-23
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
Comment
Question by:lifeform23
  • 14
  • 8
  • 6
29 Comments
 
LVL 4

Expert Comment

by:gdexter
ID: 11916847
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
 

Author Comment

by:lifeform23
ID: 11917203
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
 
LVL 4

Expert Comment

by:gdexter
ID: 11933090
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
 
LVL 4

Expert Comment

by:gdexter
ID: 11933420
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
 
LVL 8

Expert Comment

by:wguerram
ID: 11934390
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
 
LVL 8

Expert Comment

by:wguerram
ID: 11936290
Check this in order to find a node by key:

http://support.microsoft.com/default.aspx?scid=kb;en-us;311318
0
 

Author Comment

by:lifeform23
ID: 11936750
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
 
LVL 4

Expert Comment

by:gdexter
ID: 11937586
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
 
LVL 4

Expert Comment

by:gdexter
ID: 11964424
Did you ever get this to work?
0
 

Author Comment

by:lifeform23
ID: 11964655
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
 
LVL 4

Expert Comment

by:gdexter
ID: 11964792
Make sure your are using this pattern variable in GetPattern Function

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

Expert Comment

by:gdexter
ID: 11964816
Post you load method so I can look at the problem when you have a chance.
0
 
LVL 8

Expert Comment

by:wguerram
ID: 11965933
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
 
LVL 8

Expert Comment

by:wguerram
ID: 11965973
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 4

Expert Comment

by:gdexter
ID: 11966211
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
 
LVL 8

Expert Comment

by:wguerram
ID: 11966793
'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
 
LVL 4

Expert Comment

by:gdexter
ID: 11966968
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
 
LVL 4

Expert Comment

by:gdexter
ID: 12146978
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
 

Author Comment

by:lifeform23
ID: 12151963
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
 

Author Comment

by:lifeform23
ID: 12152026
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
 
LVL 4

Expert Comment

by:gdexter
ID: 12155005
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
 

Author Comment

by:lifeform23
ID: 12156350
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
 
LVL 4

Expert Comment

by:gdexter
ID: 12159338
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
 

Author Comment

by:lifeform23
ID: 12207639
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
 

Author Comment

by:lifeform23
ID: 12208020
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
 
LVL 4

Expert Comment

by:gdexter
ID: 12216572
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
 
LVL 4

Expert Comment

by:gdexter
ID: 12216622
Could you post the code that you are using again...
0
 
LVL 8

Accepted Solution

by:
wguerram earned 250 total points
ID: 12249241
'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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now