Невозможно удалить строки в datagridview в vb.net - PullRequest
1 голос
/ 11 августа 2011

Мое представление данных связано с таблицей данных.Я хочу отфильтровать сетку данных, не затрагивая таблицу данных.Я знаю, что одним из способов является использование bindingsource, но источник привязки будет использовать имена столбцов в своем фильтре.Но я хочу разрешить пользователям вводить любую строку в текстовое поле для фильтрации.Поэтому я передаю datagridview по ссылке на функцию PassFilter, которая удаляет ненужные строки в datagridview.Я вижу, что он выполняет удаление строк в datagridview.Но проблема в том, что когда в форме отображается datagridview, оно остается неизменным, так же как и таблица данных.Я не понимаю, почему строки не удаляются в datagridview

Код выглядит следующим образом:

DataGridView1.DataSource = table

PassFilter(DataGridView1, m_FilterQuick.strFilter.ToLower())
Private Sub PassFilter(ByRef datagridview As DataGridView, ByVal strFilter As String)
    Dim i As Integer = 0
    Dim j As Integer = 0
    Dim containStr As Boolean = False

    While i < datagridview.Rows.Count
        j = 0
        containStr = False
        'If all cells in a row does not contain strFilter, delete this row from datagridview
        While j < datagridview.Rows(i).Cells.Count
            Dim c As DataGridViewCell = datagridview.Rows(i).Cells(j)
            If Not c.Value Is DBNull.Value Or Nothing Then
                If c.Value.ToString().ToLower().Contains(strFilter) Then
                    containStr = True
                    Exit While
                End If

            End If
            j = j + 1
        End While
        If Not containStr Then
            datagridview.Rows.RemoveAt(i)
        End If
        i = i + 1
    End While

End Sub

Ответы [ 2 ]

3 голосов
/ 11 августа 2011

Ваша большая проблема заключается в том, что вы удаляете элементы в DataGridViewRowCollection во время итерации по этой коллекции. Даже если вы не получите сообщение об ошибке «индекс вне диапазона», это приведет к удалению неправильных строк, так как значение индекса более поздних строк изменяется при удалении более ранних строк.

Что нужно сделать, вместо удаления строк в цикле строк, добавить индекс строки в List(Of Integers).

После того, как вы закончите итерацию по всем строкам в DataGridView, Reverse() ваш список и используйте значения индекса строки в вашем List для удаления строк с помощью метода RemoveAt().

Вот что я имею в виду:

Private Sub PassFilter(ByRef datagridview As DataGridView, ByVal strFilter As String)
    Dim i As Integer = 0
    Dim j As Integer = 0
    Dim containStr As Boolean = False
    ' Row indexes we'll remove later on.
    Dim deleteIndexList As List(Of Integer) = New List(Of Integer)

    While i < datagridview.Rows.Count
        j = 0
        containStr = False
        'If all cells in a row does not contain strFilter, delete this row from datagridview 
        While j < datagridview.Rows(i).Cells.Count
            Dim c As DataGridViewCell = datagridview.Rows(i).Cells(j)
            ' Note: you'll want to enclose the tests for DBNull.Value and Nothing in parens like I show here.
            If Not (c.Value Is DBNull.Value And c.Value Is Nothing) Then
                If c.Value.ToString().ToLower().Contains(strFilter) Then
                    containStr = True
                    Exit While
                End If

            End If
            j = j + 1
        End While
        If Not containStr Then
            ' Don't remove rows here or your row indexes will get out of whack!
            ' datagridview.Rows.RemoveAt(i)
            deleteIndexList.Add(i)
        End If
        i = i + 1
    End While

    ' Remove rows by reversed row index order (highest removed first) to keep the indexes in whack.
    deleteIndexList.Reverse()
    For Each idx As Integer In deleteIndexList
        datagridview.Rows.RemoveAt(idx)
    Next
End Sub
0 голосов
/ 11 августа 2011

Отображаете ли вы данные только для чтения или для редактирования?

Если вы разрешаете пользователям редактировать, можете ли вы найти способ скрыть строки, которые вы не хотите показывать, скореечем пытаться их удалить?

Если вы отображаете это как доступное только для чтения, вы можете получить данные после фильтрации и выбросить их в новое представление данных .... (некрасиво, да, но возможный вариант)

Ой, подождите ... что если вы передадите сетку данных по значению вместо ссылки, чтобы ваши изменения при удалении сохранялись?

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