void HandleSourceCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
// Firstly if we are copying the source collection into our filtered list, update
// the copy with the new changes and compute the actual index of our item in the
// sorted/grouped/filtered list.
int actualOldIndex = -1;
int actualNewIndex = -1;
bool originalList = ActiveList == SourceCollection;
if (!originalList) {
switch (e.Action) {
case NotifyCollectionChangedAction.Add:
foreach (object o in e.NewItems)
AddToFilteredAndGroupSorted (o);
actualNewIndex = IndexOf (e.NewItems [0]);
if (actualNewIndex != -1) // Maybe it was filtered out
RaiseCollectionChanged (new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, e.NewItems [0], actualNewIndex));
break;
case NotifyCollectionChangedAction.Remove:
actualOldIndex = IndexOf (e.OldItems [0]);
foreach (object o in e.OldItems)
RemoveFromFilteredAndGroup (o);
RaiseCollectionChanged (new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Remove, e.OldItems [0], actualOldIndex));
break;
case NotifyCollectionChangedAction.Replace:
actualOldIndex = IndexOf (e.OldItems [0]);
foreach (object o in e.OldItems)
RemoveFromFilteredAndGroup (o);
foreach (object o in e.NewItems)
AddToFilteredAndGroupSorted (o);
actualNewIndex = IndexOf (e.NewItems [0]);
RaiseCollectionChanged (new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Remove, e.OldItems[0], actualOldIndex));
if (actualNewIndex != -1) // Maybe it got filtered out
RaiseCollectionChanged (new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, e.NewItems [0], actualNewIndex));
break;
case NotifyCollectionChangedAction.Reset:
filteredList.Clear ();
RootGroup.ClearSubtree ();
foreach (var o in SourceCollection)
AddToFilteredAndGroup (o);
RaiseCollectionChanged (e);
break;
}
} else {
// Raise the collection changed event
RaiseCollectionChanged (e);
}
IsEmpty = ActiveList.Count == 0;
// Finally update the selected item if needed.
switch (e.Action) {
case NotifyCollectionChangedAction.Add:
if (originalList)
actualNewIndex = e.NewStartingIndex;
if (actualNewIndex <= CurrentPosition)
MoveCurrentTo (CurrentPosition + 1);
break;
case NotifyCollectionChangedAction.Remove:
if (originalList)
actualOldIndex = e.OldStartingIndex;
if (actualOldIndex < CurrentPosition) {
MoveCurrentTo (CurrentPosition - 1);
} else if (actualOldIndex == CurrentPosition) {
if (CurrentAddItem == CurrentItem)
MoveCurrentTo (CurrentPosition - 1);
else
MoveCurrentTo (CurrentPosition);
}
break;
case NotifyCollectionChangedAction.Replace:
MoveCurrentTo (CurrentPosition);
break;
case NotifyCollectionChangedAction.Reset:
MoveCurrentTo (IndexOf (CurrentItem));
break;
}
}