Handling ObservableCollection CollectionChanged Event

1.8k views Asked by At

I've seen code like the following in the Silverlight toolkit and can't understand how it is safe to do:

private void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Update the cache
    if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems != null)
    {
        for (int index = 0; index < e.OldItems.Count; index++)
        {
            _items.RemoveAt(e.OldStartingIndex);
        }
    }
}

If you remove an item from say index 5 doesn't that change the current index of every item in the _items collection after index 5 to be one less than before? So then how is it safe to continually remove items using their "old" indexes like this code does?

I'd really like to understand why this works.

Any ideas?

1

There are 1 answers

4
LBushkin On

This code looks like it is removing a contiguous set of items from a particular starting index. If you read the remove call carefully:

_items.RemoveAt( e.OldStartingIndex );  

you will notice that it is iteratively removing items from a constant index. This means it is collapsing the list by removing items in a contiguous range. This may very well be correct - assuming that is the intent of the code.

The loop executes as many times as e.OldItems.Count indicates. So (presumably) it is told how many items to remove starting from a given index.

As a general practice, you have to be careful about how you remove items from collections for a couple reasons:

  1. Item indexes do indeed change as you remove items. So care must be taken to avoid errors resulting from item index positions shifting.
  2. Mutating a list while iterating over it (as in a foreach loop or with an explicit IEnumerator) results in exceptions. You cannot mutate a list (either add or delete) while iterating - it invalidates the iterator.