Hello,
I am building a tree from a background worker, so that the user sees the tree build up "live". For nodes that are not completely filled, I want to temporarily change their default image for a "loading" image. When a node gets all its child nodes, its image is reset to default.
Here is my code :
// initialize node
node.Override.NodeAppearance.Image = index;
...
// now child nodes are to be added : change image to "loading"
node.Override.NodeAppearance.Image = (Image)Properties.Resources.ResourceManager.GetObject("loading"));
treeView.Refresh();
// tree loaded : reset initial image index
However, this does not work : all nodes keep their initial image. Even with the tree refresh I cannot see my "loading" picture.
Thank you for your help !
Well, I can't say for sure that it was hovering the mouse over the node that caused this, but my point is that there are a lot of unknowns here. You cannot control everything that happens to the tree, so passing a tree node into another thread seems like a bad idea to me. It would be a lot safer to use the node's Key, since it's just a string. Then you could use GetNodeByKey on the UI Thread to find the right node and perform whatever action you want on it.
Ok now I think that I understand... Sometimes my node reference was "null" although the node exists and is visible. So the cause may be that I hovered over that node with the mouse pointer and thus my BackgroundWorker could not access the node anymore. Is this what you mean ?
Juscher said:As long as the BackgroundWorker is active, I disable actions of the main thread that may modify nodes.
Well... like I said, I doubt that this is anything to do with the problem you are having and I don't see how it could cause the image not to update. But... I don't see how you could possibly disable everything that might possibly alter a node. You don't have access to everything that might affect the node - unless maybe you are making the tree invisible. As long as the tree is visible, the mouse could move over the node, which might cause the tree to attempt to access that node. Even if the node is not visible on the screen, when it is DataBound, you cannot ensure that the DotNet BindingManager won't try to access it's data. Of course, that's not a problem if your tree is not bound.But the point I am trying to make is that you really have to be extremely careful when using threading. There are probably a dozen other ways the node could be accessed or changed that I haven't even thought of and you cannot control.
Actually my BackgroundWorker calls a method of the treeComponent (which holds the tree) to get an UltraTreeNode Then it calls TreeSetNodeImage on this node.
As long as the BackgroundWorker is active, I disable actions of the main thread that may modify nodes.
Hi,
It's hard to read just a code snippet. This code looks okay to me at first glance.
I'm not sure about: return treeSetNodeImageImpl.Invoke(pNode,image);
I usually use this.Invoke(delegate). I'm not familiar with the syntax you used there, but it looks like it probably does the same thing.
One thing that seems like it might be a problem here is the node. Your background worker has a reference to the node? That seems very dangerous, because that node might not exist or may have been modified on the main thread while the background thread was running. But in such a case, you'd be getting an exception. I can't see how that could cause the image not to show up. Unless the reference to the node has somehow become corrupt.