Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# INotifyCollectionChanged:添加的项不会出现在给定的索引';0';_C#_Wpf - Fatal编程技术网

C# INotifyCollectionChanged:添加的项不会出现在给定的索引';0';

C# INotifyCollectionChanged:添加的项不会出现在给定的索引';0';,c#,wpf,C#,Wpf,我正在制作一个可观察的类。Add方法工作正常。但是当我尝试调用Remove()方法时,我得到以下错误: “添加的项不显示在给定索引“0”处” 但我正在将NotifyCollectionChangedAction枚举设置为删除,如下代码所示 public class ObservableOrderResponseQueue : INotifyCollectionChanged, IEnumerable<OrderResponse> { public event Noti

我正在制作一个可观察的类。Add方法工作正常。但是当我尝试调用Remove()方法时,我得到以下错误:

“添加的项不显示在给定索引“0”处”

但我正在将NotifyCollectionChangedAction枚举设置为删除,如下代码所示

    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));
        }
    }
public类observeOrderResponsequeue:INotifyCollectionChanged,IEnumerable
{
公共事件通知CollectionChangedEventHandler CollectionChanged;
私有列表_List=新列表();
公共无效添加(OrderResponse OrderResponse)
{
此._list.Add(订单响应);
如果(CollectionChanged!=null)
{
CollectionChanged(此,新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,orderResponse,0));
}
}
公共无效删除(整数索引)
{
OrderResponse order=this.\u列表[索引];
此._list.RemoveAt(索引);
如果(CollectionChanged!=null)
{
CollectionChanged(此,新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,order,index));
}
}
公共无效删除(OrderResponse OrderResponse)
{
var item=_list.Where(o=>o.OrderDetail.TrayCode==orderResponse.OrderDetail.TrayCode).FirstOrDefault();
int index=_list.IndexOf(项);
此._list.RemoveAt(索引);
如果(CollectionChanged!=null)
{
CollectionChanged(此,新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,item,index));
}
}

您确定错误发生在
删除方法中吗?错误消息和源代码表明它在
添加方法中。请尝试在
NotifyCollectionChangedEventArgs
的构造函数中使用正确的索引
\u list.Count-1

CollectionChanged(this, new NotifyCollectionChangedEventArgs(
                                              NotifyCollectionChangedAction.Add, 
                                              orderResponse, _list.Count - 1)
                 );

如果我猜的话,我会说这句话

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
有自己的
Remove(T对象)
方法:

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

这并不能使它完全线程安全,但这是一种确保引发事件不会引发空引用异常的简单方法。

我使用Reflector跟踪了这个问题,并找出了这个异常的原因,可能是因为列表中实际相等的对象的
Equals
没有返回true;或者可能是
operator=

我在传递用于在内部列表中查找的项目而不是要删除的实际项目时,尝试使用Remove参数创建新的
NotifyCollectionChangedEventArgs
时收到此异常

有一次,我将传递到
NotifyCollectionChangedEventArgs
中的项目更改为从内部列表中删除的实际项目异常

“添加的项目未显示在给定索引处..”


消失。

哪一行引发异常?您应该创建一个方法,一次添加或删除一组对象。我也遇到了此错误。最后,我在添加的对象上发现了override Equals和public static bool operator==中的一个错误。调试此错误花费了数小时,希望可以为其他人节省一些时间。如果选择是绑定到UI元素的数据,请检查集合是否正在更新(在您的情况下,当调用
Remove
时)在非UI线程上。是的,我确定我正在调用Remove方法。这就是我不明白的原因。为什么会出现此错误。@谭:您是否按照我要求的方式更改了
Add
方法?如果没有,请执行,只是为了确保!调用
List.Add
会将新元素添加到列表的末尾,即新元素是列表中的最后一个元素list,即它有索引
list.Count-1
NotifyCollectionChangedEventArgs
的构造函数要求您传入新添加对象的索引,因此您传递了
list.Count-1
。我可以确认在
删除
(!)上引发了这个完全令人困惑的异常回调,并通过将正确的索引传递给
Add
回调来修复。令人困惑的是,在
Add
(记录为a)上根本不传递任何索引也会导致此混乱的异常消息。我在实现“排序”后遇到了此问题ObservableCollection类。当您向列表中添加元素时,它不一定会添加到列表的末尾。但是,在引发“添加”的集合更改事件时操作时,WPF希望将元素添加到列表的末尾。我解决这个问题的方法是首先将元素添加到列表的末尾,然后将其移动到正确的索引。