我正在制作一个可观察的课程。 Add方法工作正常。但后来我试图调用Remove()方法我得到了这个错误:
“添加的项目不会出现在给定的索引'0'”
但是我将NotifyCollectionChangedAction枚举设置为Remove,如下面的代码所示。
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));
}
}
答案 0 :(得分:8)
您确定错误是使用Remove
方法吗?错误消息和源代码表明它在Add
方法中。尝试在_list.Count - 1
的构造函数中使用正确的索引NotifyCollectionChangedEventArgs
:
CollectionChanged(this, new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add,
orderResponse, _list.Count - 1)
);
答案 1 :(得分:2)
如果我猜,我会说这句话......
var item = _list.Where(
o => o.OrderDetail.TrayCode == orderResponse.OrderDetail.TrayCode)
.FirstOrDefault();
...因为它调用FirstOrDefault()
,可能会返回null
。设置一个断点,看看实际发生了什么。
为此,为什么要进行查询呢?由于您要传递要删除的对象,为什么不简单地执行此操作:
int index = _list.IndexOf(item);
if (index >= 0)
this._list.RemoveAt(index);
//then pass item to your eventargs since it was the object removed.
更好,因为List<T>
有自己的Remove(T object)
方法:
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
如何举起CollectionChanged
事件可能存在竞争条件。在检查null
和提升它之间,订阅者可以从事件中删除其委托。这是避免这种情况的简单方法:
// initialize it with an empty lamda so it is never null
public event NotifyCollectionChangedEventHandler CollectionChanged = (o,e) => {};
现在你可以提高它,永远不需要检查它是否为空:
public void Add(OrderResponse orderResponse)
{
this._list.Add(orderResponse);
CollectionChanged(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
orderResponse, this._list.Count - 1));
}
这不会使它完全是线程安全的,但它确保引发事件不会引发空引用异常。
答案 2 :(得分:0)
我通过Reflector找出了问题所在,并弄清楚了导致此异常的原因可能是Equals
对于列表中实际上相等的对象未返回true;或operator ==
。
答案 3 :(得分:0)
当我尝试使用 Remove 参数创建新的 NotifyCollectionChangedEventArgs
时收到此异常正在被移除。
有一次,我将传入 NotifyCollectionChangedEventArgs
的项目更改为我要从内部列表中删除异常的实际项目
“添加的项目没有出现在给定的索引..”
走了。