INotifyCollectionChanged: the added item does not appear at the given index '0'

I am making an observable class. Adding methods work fine. But then I try to call the Remove () method, I get this error:

"The added item is not displayed at the given index '0'"

but I set the NotifyCollectionChangedAction enumeration to be removed as the code below.

public class ObservableOrderResponseQueue : INotifyCollectionChanged, IEnumerable<OrderResponse> { public event NotifyCollectionChangedEventHandler CollectionChanged; private List<OrderResponse> _list = new List<OrderResponse>(); public void Add(OrderResponse orderResponse) { this._list.Add(orderResponse); if (CollectionChanged != null) { CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, orderResponse, 0)); } } public void RemoveAt(int index) { OrderResponse order = this._list[index]; this._list.RemoveAt(index); if (CollectionChanged != null) { CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, order, index)); } } public void Remove(OrderResponse orderResponse) { var item = _list.Where(o => o.OrderDetail.TrayCode == orderResponse.OrderDetail.TrayCode).FirstOrDefault(); int index = _list.IndexOf(item); this._list.RemoveAt(index); if (CollectionChanged != null) { CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); } } 
+5
c # wpf
May 04 '11 at 13:04
source share
2 answers

Are you sure the error is related to the Remove method? The error message and source code indicate that it is in the Add method. Try using the correct _list.Count - 1 index in the NotifyCollectionChangedEventArgs constructor:

 CollectionChanged(this, new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, orderResponse, _list.Count - 1) ); 
+8
May 4 '11 at 1:10 pm
source share

If I had guessed, I would say that this line ...

 var item = _list.Where( o => o.OrderDetail.TrayCode == orderResponse.OrderDetail.TrayCode) .FirstOrDefault(); 

... because it calls FirstOrDefault() , it can return null . Set a breakpoint and see what really happens.

To this end, why make this request? Since you are passing the object to be deleted, why not just do this:

 int index = _list.IndexOf(item); if (index >= 0) this._list.RemoveAt(index); //then pass item to your eventargs since it was the object removed. 

Even better, since List<T> has its own Remove(T object) method:

 this._list.Remove(item); //this may throw an exception or not if the item is not in that collection, // which is behavior you should probably retain 



Sidenotes

There is also a possible race condition in how you raise the CollectionChanged event. Between checking for null and raising the subscriber, the subscriber could remove the delegate from the event. Here is an easy way to avoid this:

 // initialize it with an empty lamda so it is never null public event NotifyCollectionChangedEventHandler CollectionChanged = (o,e) => {}; 

Now you can just pick it up and no need to check if it is null:

 public void Add(OrderResponse orderResponse) { this._list.Add(orderResponse); CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, orderResponse, this._list.Count - 1)); } 

This does not make it completely thread safe, but it is an easy way to make sure that raising the event will not result in a null reference exception.

+2
May 4 '11 at 13:52
source share



All Articles