tags:

views:

265

answers:

3
    private void WalkerRefreshNode(bool refreshAllNodes) 
    {
        TreeNode selectedNode = tree.SelectedNode;
        TreeNode bufferedNode = (TreeNode)selectedNode.Clone();
        if (SelectedNode.Tag != null)
        {
            DataRow tag = (DataRow)selectedNode.Tag;
            if (tag.Table.TableName == "example")
            {
                if ((selectedNode.Nodes.Count == 0) || refreshAllNodes)
                {
                    selectedNode.Text += emptyNodeTempText;
                    this.ActionWalk((uint)tag["task0"], bufferedNode, 5);
                    selectedNode = bufferedNode; // -- doesn't work.
                   ...
                }
                ...
            }
            ...
        }
        ...
   }

^ here is the code that I'm trying to get working. I want to be able to fully replace Selected node with custom node. However it doesn't react to my assignment and node remains unchanged. can someone help me to get over this problem?

A: 

It seems, its because "bufferedNode" is clone of node in treeview. You must find the original node in treeview and set this one as selected node.

btw. why do you clone the node? Is it necesary?

EDIT:

The reason why I'm doing that is to avoid bufferedNode setting reference to selectedNode, when I'm processing the node tree in ActionWalk() it's slow because TreeView needs to be repainted every time I add a node(slows whole operation 10x). So I wanted to fill node structure in background and then assign it to the original tree.

Did you try call "BeginUpdate" and "EndUpdate" before and after the ActionWalk()? It should prevent the repainting.

If it will not help. you need replace the original node with the cloned node, and after set them as selected.

TcKs
The reason why I'm doing that is to avoid bufferedNode setting reference to selectedNode, when I'm processing the node tree in ActionWalk() it's slow because TreeView needs to be repainted every time I add a node(slows whole operation 10x). So I wanted to fill node structure in background and then assign it to the original tree.
forcer
+2  A: 

In order to completely replace a TreeNode you will need to remove the old node from the parent node's Nodes collection, and insert the new one in the same location:

private void ReplaceNode(TreeNode oldNode, TreeNode newNode)
{
    int index = oldNode.Index;
    TreeNodeCollection nodesCollection = oldNode.Parent.Nodes;
    nodesCollection.RemoveAt(index);
    nodesCollection.Insert(index, newNode);
}

With the above method in your code, you can change your code like so:

if ((selectedNode.Nodes.Count == 0) || refreshAllNodes)
{
    selectedNode.Text += emptyNodeTempText;
    this.ActionWalk((uint)tag["task0"], bufferedNode, 5);
    ReplaceNode(selectedNode, bufferedNode); // -- should work.
    ...
}

Note that selectedNode will still refer to the old node after replacing it.

Fredrik Mörk
A: 

First of all, selectedNode is a local variable, setting it will not affect the Tree at all.

Frederik gives a good answer as how to actually replace a Node in the Tree, but based on your comments what you actually need is:

tree.BeginUpdate();
try
{
   this.ActionWalk((uint)tag["task0"], selectedNode, 5);
}
finally
{
   tree.EndUpdate();
}

And if hat isn't fast enough you'll have to consider a Backgroundworker or something like that.

Henk Holterman
as far as I know, selectedNode is reference to tree.SelectedNode, and when I tried to set something to selectedNode it applied to tree.SelectedNode. BeginUpdate() and EndUpdate() solved the problem, however it locked ability to work with the rest of nodes that aren't updated.
forcer
selectedNode is a (local) copy of the tree.SelectedNode reference. Changing it does nothing in the Tree.
Henk Holterman