2015-09-23 2 views
0

следующий код дает мне Null Reference Exception на этапе _items.Clear(), и я не могу решить, почему.NullReferenceException при удалении элементов из списка

public void PlotDate() 
    { 
     if (_data == null) return; 
     _items.Clear(); 
     _items.Add(new Graph 
     { 
      Name = "by date", 
      Items = _data.GroupBy(e => string.Format("{0:yyyy-MMM}", e.Date)) 
      .Select(g => new Item { Key = g.Key, Value = g.Sum(x => x.Size) }) 
      .OrderByDescending(e => e.Value) 
      .ToList() 
     }); 
    } 

_items является привязываемым набор графиков, которые отображаются в интерфейсе XAML. В этом случае график просто показывает круговую диаграмму суммы всех размеров в серии дат. В классе есть несколько из этих методов для отображения разных данных, которые почти идентичны, они в основном просто группируют данные по-разному.

Странно то, что первый всегда загружается только отлично, в зависимости от того, что я выбираю, но затем, когда я пытаюсь открыть второй, он выдает исключение. Когда открывается первое представление, он также запускает метод, который заполняет _data и запускается _items.Clear, поэтому он отлично работает, когда _items пуст.

Я поставил точки останова, где бы я ни думал, чтобы попытаться посмотреть, что происходит, но ничто не установлено равным нулю. Прямо перед _items.Clear шаг прогонов, _items имеет счетчик 1, то он бросает исключение сразу после того, как отсчет идет вниз до 0.

Я также попытался с помощью _items.RemoveAt(0), и положить его после добавления нового графика и он делает то же самое.

Что происходит?

Редактировать: Я включу эту деталь, которая может быть полезна. Дисплей в пользовательском интерфейсе привязывается к элементам, который определяется этим, поэтому может возникнуть проблема. Я не могу глубже понять, но определение определения для NotifyOfPropertyChange не дает никакой полезной информации.

partial void OnItemsChanged(); 
     public BindableCollection<Graph> Items 
     { 
      get { return _items; } 
      set 
      { 
       if (value == _items) 
        return; 
       _items = value; 
       OnItemsChanged(); 
       NotifyOfPropertyChange("Items"); 
      } 
     } 
+3

Похож, что '_items' является' null'. Не могли бы вы установить * точку останова * и проверить, не так ли? –

+0

Вы говорите: «он выдает исключение сразу же после того, как счетчик опустится до 0». Означает ли это «элементы».Строка clear() 'выполняется правильно, count равно 0, и она выдает исключение на следующей строке? – vesan

+0

Нет, поэтому я установил точку останова на '_items.Clear()' и проверил '_items', а число равно 1. Затем я делаю« шаг в », и исключение появляется на' _items.Clear() ', и если я снова проверьте '_items' в этой точке, число равно 0, как и должно быть, но я не уверен, почему возникает исключение. – Antyla

ответ

0

Трудно узнать, что не так, без остальной части кода. Исключение может происходить где-то еще, когда вызывается функция Clear. Для того, чтобы помочь вам отладки, вы можете настроить VS бросить NullReferenceException, где это происходит по

Debug Menu -> Исключения .. -> Common Language времени выполнения Исключения -> Система-> System.NullReferenceException -> Проверить Метательное

VS остановится в строке кода, который генерирует исключение.

+0

К сожалению, исключение по-прежнему появляется в том же месте, когда я это делаю. Выполнение всего кода было бы сложным, поскольку в него включается _lot_ зависимых частей. Я думал, что это довольно понятно, но это просто список, который не будет ясен. : \ – Antyla

+0

Обычно, по крайней мере, один из объектов в строке кода, где разрывы VS будут «null», чтобы он выбрал это исключение. Я никогда не видел ничего, что бросает исключение NullReferenceException, когда ни один из объектов не является «null». С какими объектами связан ваш '_items'? Возможно, объект привязки сделан вместо «null». –

0

Возможно, _items является null. Просто добавьте точку останова на строке _items.Clear() и отлаживайте приложение.

+0

Я пробовал это, '_items' не является нулевым, когда выполняется шаг' _items.Clear() '. – Antyla

+0

Я думаю, вам следует разделить запрос LINQ на несколько строк. Таким образом, это поможет вам понять, где вы получаете нуль. – ohadinho

+0

Вы связали обработчик для события смены коллекции? – ohadinho

0

Из трассировки стека я вижу, что исключение вызывается в событии OnCollectionChanged, которое запускается вызовом Clear(). Таким образом, вы должны проверить, что происходит в этом случае, и это должно быть показано ранее

System.Collections.ObjectModel.ObservableCollection1.OnCollectionChanged (Notify CollectionChangedEventArgs е)

линии в трассировки стека.

+0

Вот строки заранее, я не уверен, что они будут полезны: в System.Windows.WeakEventManager.DeliverEventToList (отправитель объекта, аргументы EventArgs, список ListenerList) в System.Windows.WeakEventManager.DeliverEvent (отправитель объекта , EventArgs арг) на System.Windows.Data.CollectionView.OnCollectionChanged (NotifyCollectionChangedEventArgs арг) на System.Windows.Data.ListCollectionView.RefreshOverride() на System.Windows.Data.CollectionView.RefreshInternal() – Antyla

+0

Там это, который может быть полезно, хотя это не то место, где выбрано исключение, и я не могу получить доступ к определению для NotifyOfPropertyChange. 'partial void OnItemsChanged(); \t \t общественного BindableCollection Элементы \t \t { \t \t \t GET {возвращение _items; } \t \t \t \t установить \t \t { \t \t \t \t, если (значение == _items) \t \t \t \t \t возврата; \t \t \t \t _items = значение; \t \t \t \t OnItemsChanged(); \t \t \t \t NotifyOfPropertyChange ("Items"); \t \t \t \t \t} – Antyla