Hey,
I'm on a roll tonight! (This may be related to the other one) Let's say I have directory A, which has children B,C,D,E,F,G. B has children H,I,J. C has a child K. First I delete B by doing A.Children.Remove(B). Then I move K to have A as a parent: C.Children.Remove(K). A.Children.Add(K). Now it thinks you've added K twice, and it barfs at you. After a few hours of poking through your code, I found this is because the internal Index of C was messed up after I removed B. So when I tried to remove C, it remved the wrong item! I think this is because the code is forgetting that it is also removing children when it removes tasks with children... Specificly, I think (might be wrong here) that the code in HierarchicalCollectionAdapterBase is not taking this into account (see below). I should be able to make a simple program to show this bug if nessesary. Probably what I will end up doing is the DFS myself to hierarchicly remove each item I need to....
Eric
As always, using 2012 Q2 wpf
I'm on a roll tonight! (This may be related to the other one) Let's say I have directory A, which has children B,C,D,E,F,G. B has children H,I,J. C has a child K. First I delete B by doing A.Children.Remove(B). Then I move K to have A as a parent: C.Children.Remove(K). A.Children.Add(K). Now it thinks you've added K twice, and it barfs at you. After a few hours of poking through your code, I found this is because the internal Index of C was messed up after I removed B. So when I tried to remove C, it remved the wrong item! I think this is because the code is forgetting that it is also removing children when it removes tasks with children... Specificly, I think (might be wrong here) that the code in HierarchicalCollectionAdapterBase is not taking this into account (see below). I should be able to make a simple program to show this bug if nessesary. Probably what I will end up doing is the DFS myself to hierarchicly remove each item I need to....
Eric
As always, using 2012 Q2 wpf
var startIndex = collectionChangedAction == NotifyCollectionChangedAction.Remove ? oldStartingIndex : newStartingIndex; var newWrappers = newItemsCollection != null ? newItemsCollection.OfType<HierarchicalItem>() : Enumerable.Empty<HierarchicalItem>(); var newItemsCount = newItemsCollection != null ? newItemsCollection.Count : 0; var oldWrappers = oldItemsCollection != null ? oldItemsCollection.OfType<HierarchicalItem>() : Enumerable.Empty<HierarchicalItem>(); var oldItemsCount = oldItemsCollection != null ? oldItemsCollection.Count : 0; var removedWrappers = oldWrappers.SelectMany(Flatten).ToArray(); var addedWrappers = newWrappers.SelectMany(Flatten).ToArray(); var sourceCollectionItemsCountDifference = newItemsCount - oldItemsCount; var childrenCountDifference = addedWrappers.Length - removedWrappers.Length - sourceCollectionItemsCountDifference; for (int i = startIndex + newItemsCount; i < targetCollection.Count; i++) { targetCollection[i].previousChildrenCount += childrenCountDifference; targetCollection[i].SourceItemIndex += sourceCollectionItemsCountDifference; } var previousChildrenCount = startIndex > 0 ? targetCollection[startIndex - 1].previousChildrenCount + targetCollection[startIndex - 1].visibleChildrenCount : 0; foreach (var newWrapper in newWrappers) { newWrapper.previousChildrenCount += previousChildrenCount; previousChildrenCount += newWrapper.visibleChildrenCount; }