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;
}