Каждая вторая строка, попадающая во время для каждого в DataGridViewRow с удалением

#.net #vb.net #datagridview #foreach

#.net #vb.net #просмотр сетки данных #foreach #datagridview

Вопрос:

Предположим, у меня есть вызываемый DataGridView gridFiles .

 For Each row as DataGridView in gridFiles.Rows
    MsgBox(row.Cells("somekey").Value.ToString)
    gridFiles.Rows.Remove(row)
Next
  

Я увижу окна сообщений, но только для каждой второй строки. Я думаю, что происходит то, что внутренний указатель на gridFiles.Rows отключается, потому что на следующей итерации на 1 строку меньше.

Мне нужно выполнить итерацию по каждой строке и условно решить, удалять их или нет (на основе успеха или неудачи другого действия).

Как я могу обойти эту проблему?

Ответ №1:

 dim deleteList As new List(Of DataGridViewRow)
For Each row as DataGridViewRow in gridFiles.Rows
    MsgBox(row.Cells("somekey").Value.ToString)
    deleteList.Add(row)
Next
For Each row As DataGridViewRow in deleteList 
   gridFiles.Rows.Remove(row)
Next
  

Или измените коллекцию в обратном направлении

 For i As Integer = gridFiles.Rows.Count - 1 To 0 Step -1
    MsgBox(row.Cells("somekey").Value.ToString)
    gridFiles.Rows.Remove(gridFiles.Rows(i))
End If
  

Ответ №2:

Когда вы выполняете итерацию по коллекции gridFiles.Rows и удаляете из этой коллекции, вы нарушаете саму коллекцию, и итерация работает не так, как должна (foreach пытается получить следующее значение, но индекс изменился из-за элемента, который был удален), оставляя вас с оценкой «every other».

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

Комментарии:

1. : o) Магнус написал хорошую демонстрацию того, что я только что объяснил.

2. Я удивлен, что это не создает исключения.

3. Ни одна отдельная команда в последовательности не является «плохой» сама по себе. Проблема заключается в порядке выполнения операций. Если вы посмотрите на второй пример, предложенный Магнусом, если вы не выполните итерацию в обратном направлении, вы получите исключение, потому что i будет превышать фактический индекс.