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 !
By the way, I am using an UltraTree control of 2008. Maybe it would work better with a newer version of WinForms ?
Hello Brian,
you are right, I have to update the tree from the BackgroundWorker in order to have the tree usable during its loading.
Since I am using delegates to do this properly (I have to because otherwise my application would crash), I think the multithreading aspect is handled properly. Or maybe a delegate is not enough ?
My project is quite big so it is not possible that I send it to you as a sample, but my code is very simple on this aspect. Here is the code called from the BackgroundWorker :
int imageIndex = _treeComponent.TreeSetNodeImage(parentNode, (Image)Properties.Resources.ResourceManager.GetObject("loading"));
Where _treeComponent is a component which contains my UltraTree.
The method TreeSetNodeImage is implemented like this :
/// <summary> /// Delegate for setting the image of a node /// </summary> /// <returns>Old image index</returns> private delegate int TreeSetNodeImageDel(UltraTreeNode pNode, Image image); /// <summary> /// Sets the image of a node threadsave /// </summary> /// <param name="pNode">The node</param> /// <param name="image">The image</param> /// <returns>Old image index</returns> internal int TreeSetNodeImage(UltraTreeNode pNode, Image image) { if (this.InvokeRequired) { TreeSetNodeImageDel treeSetNodeImageImpl = TreeSetNodeImageImpl; return treeSetNodeImageImpl.Invoke(pNode,image); } return TreeSetNodeImageImpl(pNode,image); } /// <summary> /// Sets the image of a node /// </summary> /// <param name="pNode">The node</param> /// <param name="image">The image</param> /// <returns>Old image index</returns> internal int TreeSetNodeImageImpl(UltraTreeNode pNode, Image image) { int imageIndex = (int)pNode.Override.NodeAppearance.Image; pNode.Override.NodeAppearance.Image = image; TreeRefresh(); return imageIndex; }
I hope this will help you understand what is going on.
It is difficult to speculate without additional details. One thing to note is that you cannot update the tree's images (or anything else for that matter) from the BackgroundWorker's DoWork event, so if you are doing it there that would explain the problem. Documentation for the BackgroundWorker class explains how the properly implement this kind of thing.
If you are confident that you are handling the multithreading aspect of this correctly, and you are able, attach a sample project here and we can take a look.