Select a treeview node by its path

A

André Nogueira

Hi there.
I know you can view a node's fullpath property, but is it posible to select
a node using its path?
Like, tell the treeview that the node that should be selected is the node
with the path "Users\Administrators\John Doe"?
Thank you in advance!

Andre Nogueira
 
H

Herfried K. Wagner [MVP]

* "André Nogueira said:
I know you can view a node's fullpath property, but is it posible to select
a node using its path?
Like, tell the treeview that the node that should be selected is the node
with the path "Users\Administrators\John Doe"?

Set up a hashtable that stores (fullpath, 'TreeNode') pairs. Then you
can lookup the treenodes by their path and set the treeview's
'SelectedNode' property to the specific node.
 
A

André Nogueira

Thanks!
I've never used hashtables before, but I'll look it up.

Andre Nogueira
 
A

André Nogueira

Worked like a charm!
Thank you once more for all the times you had the time and patience needed
to help me out!
You really deserve the MVP status and its people like you that save the
lifes of people like me =)

André Nogueira
 
A

André Nogueira

I'm having a problem.
This is the code I am using

<...>
Dim a As SizeTreeNode = HashTable.Item(path)
Me.TreeView1.SelectedNode = a
a.Parent.ExpandAll
<...>

Why doesn't this work? What am I doing wrong?
The node is neither selected nor expanded.
If I do

MsgBox(a.Text)
MsgBox(Me.TreeView1.SelectedNode.Text)


I see that "a" is the correct node, but the selected node is the node that
was selected prior to that statement. So what am I missing here?
Thanks again!

André Nogueira
 
H

Herfried K. Wagner [MVP]

* "André Nogueira said:
This is the code I am using

<...>
Dim a As SizeTreeNode = HashTable.Item(path)
Me.TreeView1.SelectedNode = a
a.Parent.ExpandAll
<...>

Why doesn't this work? What am I doing wrong?
The node is neither selected nor expanded.

Set the treeview's 'HideSelection' property to 'False' to check if the
node is selected even if the treeview control doesn't have the focus.
If I do

MsgBox(a.Text)
MsgBox(Me.TreeView1.SelectedNode.Text)


I see that "a" is the correct node, but the selected node is the node that
was selected prior to that statement. So what am I missing here?

Are you sure you placed this code after setting the 'SelectedNode'? To
check if the selected node has been set, use 'If
Me.TreeView1.SelectedNode Is a Then...' after setting the selected node.
 
J

Jay B. Harlow [MVP - Outlook]

André,
In addition to the other comments.

You could "walk" the Node.Nodes collection to find your node of interest.
However depending on the amount of data & how often I wanted to select a
specific node I might go with the other suggestion.

Here's a custom Tree View that adds a SelectedPath property, instead of
putting a TreeView on your Form, put a MyTreeView (I will add a TreeView in
the designer then carefully change System.Windows.Forms.TreeView to
MyTreeView), then in code or the properties window enter the path of the
requested Node.

Option Strict On
Option Explicit On

Public Class MyTreeView
Inherits TreeView

<System.ComponentModel.DefaultValue("")> _
Public Property SelectedPath() As String
Get
If MyBase.SelectedNode Is Nothing Then
Return String.Empty
Else
Return MyBase.SelectedNode.FullPath
End If
End Get
Set(ByVal value As String)
If value = String.Empty Then
MyBase.SelectedNode = Nothing
Exit Property
End If
Dim paths() As String = Split(value, MyBase.PathSeparator)
Dim nodes As TreeNodeCollection
Dim node As TreeNode
For Each path As String In paths
If nodes Is Nothing Then
nodes = MyBase.Nodes
ElseIf Not node Is Nothing Then
nodes = node.Nodes
End If
For Each child As TreeNode In nodes
If child.Text = path Then
node = child
Exit For
End If
Next
Next
If value = node.FullPath Then
MyBase.SelectedNode = node
Else
Throw New ArgumentOutOfRangeException("SelectedPath", value,
"SelectedPath not found")
End If

End Set
End Property

End Class


Hope this helps
Jay
 
A

André Nogueira

This is the code I'm using

Dim a As SizeTreeNode = HT.Item(Lvi.path)
Me.TreeView1.SelectedNode = a
MsgBox(Me.TreeView1.SelectedNode Is a)
MsgBox(a.Text)
MsgBox(Me.TreeView1.SelectedNode.Text)
a.Parent.ExpandAll

The first msgbox returns "false", the other two return what I have told you.
So... What is the problem?
SizeTreeNode is a class that inherits from the treenode but adds a few
properties I need for my program. All nodes on the treeview are
SizeTreeNodes and the values added to the hashtable are also SizeTreeNodes.

André Nogueira
 
A

André Nogueira

If I do

a = Me.TreeView1.SelectedNode.Parent
Me.TreeView1.SelectedNode = a
MsgBox(Me.TreeView1.SelectedNode Is a)
MsgBox(a.Text)
MsgBox(Me.TreeView1.SelectedNode.Text)

It works.
I did this to see if it was a problem with the selectednode property or
something. This sets the selected node to parent of the currently selected
node and it works.
This isn't what I want to do, this is just an experiment.
So what am I doing wrong with my other code?

André Nogueira
André Nogueira said:
This is the code I'm using

Dim a As SizeTreeNode = HT.Item(Lvi.path)
Me.TreeView1.SelectedNode = a
MsgBox(Me.TreeView1.SelectedNode Is a)
MsgBox(a.Text)
MsgBox(Me.TreeView1.SelectedNode.Text)
a.Parent.ExpandAll

The first msgbox returns "false", the other two return what I have told
you.
So... What is the problem?
SizeTreeNode is a class that inherits from the treenode but adds a few
properties I need for my program. All nodes on the treeview are
SizeTreeNodes and the values added to the hashtable are also
SizeTreeNodes.

André Nogueira
 
A

André Nogueira

I think I see the problem here.
I think the node in the Hashtable is just a copy (a clone) of the node on
the treeview. As such, the program sees the node on the treeview and the
node on the hashtable as two different nodes.
This can be verified if I do

Me.TreeView1.SelectedNode.Nodes.Add(a)

It will then add a copy of the node to the selected node, leaving that node
with two nodes which are the same.
Any other suggestions?

André Nogueira
 
H

Herfried K. Wagner [MVP]

* "André Nogueira said:
a = Me.TreeView1.SelectedNode.Parent
Me.TreeView1.SelectedNode = a
MsgBox(Me.TreeView1.SelectedNode Is a)
MsgBox(a.Text)
MsgBox(Me.TreeView1.SelectedNode.Text)

It works.
I did this to see if it was a problem with the selectednode property or
something. This sets the selected node to parent of the currently selected
node and it works.
This isn't what I want to do, this is just an experiment.
So what am I doing wrong with my other code?

It seems that there is a problem with 'ExpandAll', if I understand your
posts. Mhm, I don't have an idea...
 
A

André Nogueira

Thank you! Your treeview works great.
One bug though:
If a node has in its path a path separator character, the property won't
work.
Example:
A treeview with
- C:\
----windows
----system32
would have the path C:\\windows\system32 which would cause your treeview to
cast an error.
This could be resolved by replacing every two Path separators with just one
until there are no more two path separator characters together. However,
this would not work if you have nodes with no text.
But this isn't a big problem to me, so... I'm good :)
Thanks again

André Nogueira
 
H

Herfried K. Wagner [MVP]

* "André Nogueira said:
I think I see the problem here.
I think the node in the Hashtable is just a copy (a clone) of the node on
the treeview. As such, the program sees the node on the treeview and the
node on the hashtable as two different nodes.
This can be verified if I do

Me.TreeView1.SelectedNode.Nodes.Add(a)

It will then add a copy of the node to the selected node, leaving that node
with two nodes which are the same.
Any other suggestions?

'TreeNode' is a class, and thus not a value type. So, a reference to
the same instance should be stored in the hashtable.

I suggest to turn 'Option Strict On', this will help you to identify
bugs in the code more easily. In your existing code, you will have to
change

\\\
Dim t As TreeNode = MyNodesHashtable.Item(Key)
///

to

\\\
Dim t As TreeNode = DirectCast(MyNodesHashtable.Item(Key), TreeNode)
///

This is not the reason why your code is not working, but it's at least a
starting point.
 
A

André Nogueira

I had already tried with CType, but to no avail.
Will try that now.

Andre Nogueira
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top