INotifyCollectionChanged: добавленный элемент не отображается с указанным индексом '0' - PullRequest
7 голосов
/ 04 мая 2011

Я делаю наблюдаемый класс.Методы 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));
        }
    }

Ответы [ 3 ]

8 голосов
/ 04 мая 2011

Вы уверены, что ошибка в методе Remove? Сообщение об ошибке и ваш исходный код указывают, что это метод Add. Попробуйте использовать правильный индекс _list.Count - 1 в конструкторе NotifyCollectionChangedEventArgs:

CollectionChanged(this, new NotifyCollectionChangedEventArgs(
                                              NotifyCollectionChangedAction.Add, 
                                              orderResponse, _list.Count - 1)
                 );
2 голосов
/ 04 мая 2011

Если бы я угадал, я бы сказал, что эта строка ...

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

Sidenotes

Существует также возможное состояние гонки в том, как вы поднимаете событие CollectionChanged. Между проверкой null и ее поднятием абонент может удалить своего делегата из события. Вот простой способ избежать этого:

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

Теперь вы можете просто поднять его, и вам больше не нужно проверять, имеет ли оно значение null:

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

Это не делает его полностью поточно-ориентированным, но это простой способ убедиться, что повышение события не вызовет исключение нулевой ссылки.

0 голосов
/ 27 ноября 2018

Я обнаружил проблему с Reflector и выяснил, что причина этого исключения может относиться к Equals, не возвращающему true для фактически равных объектов в вашем списке; или, может быть, operator ==.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...