tags:

views:

427

answers:

3

Hi, Im using following code:

TreeNode i = treeView1.SelectedNode;

RefillTree(); //clears the tree and rebuilt it again.

treeView1.SelectedNode=i;

However, SelectedNode still remains null, however "i" is correctly referencing.

I would need to select and expand particular node automatically after tree refresh.

Thank you

+2  A: 

What does "RefillTree" do exactly? If it removes the Node referenced by 'i', then I would expect that setting the SelectedNode property to a node that does not exist in the control would have no effect.

EDIT:

I can almost guarantee that you are clearing the control and creating new nodes to fill it with. It does not matter if these new nodes contain the same data, SelectedNode looks for object equality and it doesn't find a match. for example, this code reproduces your problem:

treeView1.nodes.Add( new TreeNode( "Node 1" ) );
treeView1.nodes.Add( new TreeNode( "Node 2" ) );
treeView1.SelectedNode = new TreeNode( "Node 1" );  

// null reference exception here, we did not find a match
MessageBox.Show( treeView1.SelectedNode.ToString( ) );

So, you can instead find the node by value after clearing the control:

TreeNode node1 = new TreeNode( "Node 1" );          
TreeNode node2 = new TreeNode( "Node 2" );                          

treeView1.Nodes.Add( node1 );
treeView1.Nodes.Add( node2 );

treeView1.Nodes.Clear( );

treeView1.Nodes.Add( "Node 1" );
treeView1.Nodes.Add( "Node 2" );

// you can obviously use any value that you like to determine equality here
var matches = from TreeNode x in treeView1.Nodes
              where x.Text == node2.Text
              select x;
treeView1.SelectedNode = matches.First<TreeNode>( );

// now correctly selects Node2
MessageBox.Show( treeView1.SelectedNode.ToString( ) );

Using LINQ here seems clunky, but the TreeNodeCollection class only exposes a Find() method which uses the node's Name property. You could also use that, but equally clunky.

Ed Swangren
Hmm yes, it clears and rebuilds again the whole nodestructure. But it remains the same. When specific node is selected, the program shows DB data assigned to its name.So is there some way how to select and open the node which was selected before?
Petr
Perhaps you could post the body of RefillNodes for us.
Ed Swangren
BTW, even if the text is the same, if you are adding new nodes the objects are different.
Ed Swangren
Sorry its pretty long, filling with DB, but basically it clears the tree and then create the structure again.So now the question is how to to store selected node and re-select it after tree refresh?
Petr
But the refilling of the structure is the important bit. I would bet that you are creating new TreeNode objects when filling the tree, so when you set selected node, well, it no longer exists. See new edit.
Ed Swangren
Thank you, I understand now :) Still forggeting on object equality.
Petr
A: 

RefillTree is replacing the node, so i no longer exists when you attempt to reset the selected node.

EDIT: Try this code

    Dim RememberMe As String = TreeView1.SelectedNode.Name()

    RefillTree()

    Dim FoundNode() As TreeNode = TreeView1.Nodes.Find(RememberMe, True)
    If FoundNode.Length > 1 Then
        ' oops, we didn't give unique values!
    Else
        TreeView1.SelectedNode = FoundNode(0)
    End If
Rip Rowan
well, probably, but not necessarily since we don't know what RefillTree is doing as the OP has not posted that code.
Ed Swangren
It's obvious, since the node object is vanishing :)My solution will work regardless of what RefillTree() is doing.
Rip Rowan
Yes, I did say probably, very, very... probably :)
Ed Swangren
Name will be an empty string unless it has been assigned to previously.
Ed Swangren
1. Your proposed (and accepted) answer will only work if the Text property is unique. IMO the name property should be assigned with a unique value (ie database key)2. I think I answered this question.
Rip Rowan
The OP can obviously use any value they would like, the example is just that; an example. "I think I answered this question." - that's nice.
Ed Swangren
Nice. Vote me down even when I offer a (probably better) working solution.Not cool at all.
Rip Rowan
+1  A: 

Finding the node by name will work, however watch out if you have multiple nodes with the same name while under different branches.

A good solution I use is to save the selected node's path:

selected_node_path = tree.SelectedNode.FullPath

Then when you're rebuilding the treeview structure, set the added node as selected, after it has been added to the tree:

 ' create your node
 newnode = New TreeNode("node name")
 ' add it to the tree, it then gets a path
 tree.Nodes.Add(newnode)
 ' test if it's the same path
 If (newnode.FullPath = selected_node_path) Then tree.SelectedNode = newnode

PS don't mind the VB, but you get the general idea

Wez