Menu

#178 Exception in RefreshObjects() where one of the object in argument is being removed during refresh

C#_v2.9
open
None
4
2018-10-15
2018-10-15
No

Hi, I encounter an exception when refreshing tree view nodes.

In my application, for every second I refresh all the expanded node like follow:
treeView.RefreshObjects(treeView.ExpandedObjects)

Suppose initially we have a tree structor like this:
root
|--node1
|--node2
|--node3

So root, node1, node2 are expanded and will be considered by RefreshObjects() by the function

Suppose the tree model now become this:
root
|--node1

So on the second refresh iteration, RebuildChildren() will call this.objectList.RemoveRange() for node2 and node3; however mapObjectToIndex and mapObjectToBranch were not update, they will leak memory.

On the third iteration, it try to update node2 which was no longer in the model, but still able to find in mapObjectToBranch, and will trigger objectList.RemoveRange() which then causing array out of range exception.

My purposed fix:

public virtual int RebuildChildren(Object model) {
if(!this.mapObjectToIndex.ContainsKey(model))
return -1;

Branch br = this.GetBranch(model);
if (br == null || !br.Visible)
    return -1;

int count = br.NumberVisibleDescendents;

// Remove the visible descendents from after the branch itself
int index = this.GetObjectIndex(model);
if(count > 0)
{
    this.objectList.RemoveRange(index + 1, count);
    this.RebuildObjectMap(0);
}

// Refresh our knowledge of our children (do this even if CanExpand is false, because
// the branch have already collected some children and that information could be stale)
br.RefreshChildren();

// Insert the refreshed children if the branch can expand and is expanded
if (br.CanExpand && br.IsExpanded)
    this.InsertChildren(br, index + 1);
else
    this.RebuildObjectMap(index);

return index;

}

Regards,
Ricky Lung

Discussion


Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.