Почему ItemContainerGenerator.ContainerFromIndex () возвращает null и как избежать этого поведения?

Я использую этот фрагмент для анализа строк, которые я выбрал на datagrid.

for (int i = 0; i < dgDetalle.Items.Count; i++)
{
    DataGridRow row = (DataGridRow)dgDetalle.ItemContainerGenerator.ContainerFromIndex(i);
    FrameworkElement cellContent = dgDetalle.Columns[0].GetCellContent(row);
    // ... code ...
}

цикл работает плавно, но при обработке определенных индексов вторая строка выдает исключение null. В документации MSDN говорится, что ItemContainerGenerator.ContainerFromIndex(i) вернет null, если "если элемент не реализован", но это не поможет мне догадаться, как я могу получить желаемое значение.

как я могу сканировать все строки? Есть ли другие способ?

обновление

Я использую этот фрагмент для чтения CheckBox Как пояснил здесь. Поэтому я не могу использовать binding или ItemSource вообще, если я не изменю много вещей. А я не могу. Я занимаюсь обслуживанием кода.

3 ответов


на DataGrid виртуализирует элементы, соответствующие строки (т. е. контейнеры) создаются только тогда, когда строка находится в поле зрения.

можно отключить виртуализацию (что делает первую загрузку очень медленной, если у вас много элементов, также использование памяти будет выше) или вы просто повторяете данные и проверяете значения свойств объектов данных, которые должны быть привязаны к сетке данных. Обычно вам не нужны элементы UI на все...


попробуйте это,

DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
                          grid.UpdateLayout();
            grid.ScrollIntoView(grid.Items[index]);
            row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        }

использовать эту подписку:

TheListBox.ItemContainerGenerator.StatusChanged += (sender, e) =>
{
  TheListBox.Dispatcher.Invoke(() =>
  {
     var TheOne = TheListBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
       if (TheOne != null)
         // Use The One
  });
};