0

In my Windows Explorer type app with the obligatory Treeview and Listview, and having the users chosen file path continually updating in a Textbox, is there a way to navigate to different nodes in the Treeview using the actual file path directly? The Text and Tag of each node is the same. This would be useful for instance, to duplicate Explorer's "Up" button among other things, but I cant seem to find any information on it other than lengthy looping processes. Any suggestions would be appreciated.

This is the code I have tried:

Imports System.IO
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        TreeView1.HideSelection = False
        For Each Drive In DriveInfo.GetDrives
            If (Drive.IsReady) Then
                Dim dName As String = Drive.VolumeLabel
                If String.IsNullOrEmpty(dName) Then
                    dName = Drive.Name
                End If

                Dim tNode As New TreeNode()

                With tNode
                    .ImageIndex = 0
                    .SelectedImageIndex = 0
                    .Text = dName
                    .Nodes.Add("")
                    .Tag = dName
                End With
                TreeView1.Nodes.Add(tNode)
            End If
        Next

        'Dim TreeNode1 As TreeNode = New TreeNode("Private")
        'Dim TreeNode2 As TreeNode = New TreeNode("Public")
        'Dim TreeNode3 As TreeNode = New TreeNode("Data", New TreeNode() {TreeNode1, TreeNode2})
        'Dim TreeNode4 As TreeNode = New TreeNode("Pictures")
        'Dim TreeNode5 As TreeNode = New TreeNode("C:", New TreeNode() {TreeNode3, TreeNode4})

        'TreeView1.HideSelection = False
        'TreeView1.Name = "TreeView1"
        'TreeNode1.Name = "C:\Data\Private"
        'TreeNode1.Text = "Private"
        'TreeNode2.Name = "C:\Data\Public"
        'TreeNode2.Text = "Public"
        'TreeNode3.Name = "C:\Data"
        'TreeNode3.Text = "Data"
        'TreeNode4.Name = "C:\Pictures"
        'TreeNode4.Text = "Pictures"
        'TreeNode5.Name = "C:"
        'TreeNode5.Text = "C:"
        'TreeView1.Nodes.AddRange(New TreeNode() {TreeNode5})

    End Sub

    Private Sub TreeView1_BeforeExpand(sender As Object, e As TreeViewCancelEventArgs) Handles TreeView1.BeforeExpand
        GetFolders(e.Node)
    End Sub

    Private Sub GetFolders(ByVal PathName As TreeNode)
        Dim di As DirectoryInfo
        PathName.Nodes.Clear()
        di = New DirectoryInfo(PathName.Tag)

        Try
            For Each nFolder In di.GetDirectories()
                Dim tNode As New TreeNode()

                With tNode
                    .ImageIndex = 1
                    .SelectedImageIndex = 1
                    .Tag = nFolder.FullName
                    .Text = nFolder.Name.ToString()
                    .Nodes.Add("")
                End With

                di = New DirectoryInfo(tNode.Tag)

                If (di.Attributes And FileAttributes.Hidden) = False Then
                    PathName.Nodes.Add(tNode)
                End If

            Next
        Catch ex As Exception
        End Try
    End Sub

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        Dim nodes As TreeNode() = TreeView1.Nodes.Find(TextBox1.Text, True)
        If nodes.Length > 0 Then
            Dim selectedNode As TreeNode = nodes(0)
            TreeView1.SelectedNode = selectedNode
            selectedNode.Expand()
            selectedNode.EnsureVisible()
        End If
    End Sub
End Class

If I just run your code, it works fine. Mine however, loading the file structure doesn't "Find"

1 Answer 1

0

There is a Find method in the TreeNodeCollection. It returns an array of found nodes matching the Name property of a node.

I have set up a little test Form in the Forms designer (excerpt from Form1.Designer.vb):

Private Sub InitializeComponent()
    Dim TreeNode1 As TreeNode = New TreeNode("Private")
    Dim TreeNode2 As TreeNode = New TreeNode("Public")
    Dim TreeNode3 As TreeNode = New TreeNode("Data", New TreeNode() {TreeNode1, TreeNode2})
    Dim TreeNode4 As TreeNode = New TreeNode("Pictures")
    Dim TreeNode5 As TreeNode = New TreeNode("C:", New TreeNode() {TreeNode3, TreeNode4})
    TreeView1 = New TreeView()
    TextBox1 = New TextBox()
    SuspendLayout()
    '
    ' TreeView1
    ' 
    TreeView1.HideSelection = False
    TreeView1.Location = New Point(55, 213)
    TreeView1.Name = "TreeView1"
    TreeNode1.Name = "C:\Data\Private"
    TreeNode1.Text = "Private"
    TreeNode2.Name = "C:\Data\Public"
    TreeNode2.Text = "Public"
    TreeNode3.Name = "C:\Data"
    TreeNode3.Text = "Data"
    TreeNode4.Name = "C:\Pictures"
    TreeNode4.Text = "Pictures"
    TreeNode5.Name = "C:"
    TreeNode5.Text = "C:"
    TreeView1.Nodes.AddRange(New TreeNode() {TreeNode5})
    TreeView1.Size = New Size(262, 144)
    TreeView1.TabIndex = 3
    ' 
    ' TextBox1
    ' 
    TextBox1.Location = New Point(55, 364)
    TextBox1.Name = "TextBox1"
    TextBox1.Size = New Size(262, 23)
    TextBox1.TabIndex = 4
    ' 
    ' Form1
    ' 
    AutoScaleDimensions = New SizeF(7F, 15F)
    AutoScaleMode = AutoScaleMode.Font
    ClientSize = New Size(800, 450)
    Controls.Add(TextBox1)
    Controls.Add(TreeView1)
    Name = "Form1"
    Text = "Form1"
    ResumeLayout(False)
    PerformLayout()
End Sub

Friend WithEvents TreeView1 As TreeView
Friend WithEvents TextBox1 As TextBox

Then I added this TextChanged event handler:

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    Dim nodes As TreeNode() = TreeView1.Nodes.Find(TextBox1.Text.TrimEnd("\"c), True)
    If nodes.Length > 0 Then
        Dim selectedNode As TreeNode = nodes(0)
        TreeView1.SelectedNode = selectedNode
        selectedNode.Expand()
        selectedNode.EnsureVisible()
    Else
        ' Deselect the node if no match.
        TreeView1.SelectedNode = Nothing
    End If
End Sub

Now, when I type a path, the selected node is continuously updated. Note that the Name of a node is the whole path up to this point, while the display Text is only a portion of the path.

.TrimEnd("\"c) trims the last backslash from the text, so that we get a match while we are typing. E.g., we have a Name property "C:\Data", so when we type "C:\Data\" we still get a match.

The second parameter Truein theFind` call says that we want to find sub-nodes as well.

It helps to set TreeView1.HideSelection = False to display the Node selection even when the focus in the TextBox.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much for this, the code is exactly what I'm looking for. Unfortunately, whilst your code works correctly as it is, when I load the the Treeview by code in the normal way - For Each Drive In DriveInfo.GetDrives etc, I can't seem to get the Find Function working. I would have liked to show you my code but can't see how to add it as a comment. Many Thanks
You can always edit your question and add additional info there. It depends on what is stored in Name. If Name contains C, but you are typing C:, then you will not find it. See also: Tutorial: Learn to debug Visual Basic code using Visual Studio.
Many thanks, have added the code above. If I REM out my code and run your data, it works fine,
Apologies, I didn't explain myself well. I was trying to explain that when I loaded the Treeview with your data, it worked correctly. However, when I load the Treeview in any other way, it doesn't work. I've tried to understand why but can't see it. I upload my code to ask if you could see why that was. Sorry for the confusion.
You are never setting the TreeNode's Name. The Find function looks for Name property. Not the Tag nor the Text property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.