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"
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 the
Find` 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.