无法删除vb.net中datagridview中的行

时间:2011-08-11 15:50:10

标签: vb.net datagridview filter rows

我的datagridview绑定到数据表。我想过滤datagridview而不影响数据表。我知道一种方法是使用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 个答案:

答案 0 :(得分:3)

您遇到的最大问题是,在迭代该集合时,您正在删除DataGridViewRowCollection中的项目。即使您没有得到“索引超出范围”错误,但是当您删除先前的行时,您将最终删除错误的行,因为后续行的索引值会发生变化。

您应该做的不是删除行循环中的行,而是将行的索引添加到List(Of Integers)

完成迭代DataGridView中的所有行后,Reverse()列表并使用List中的行索引值通过RemoveAt()方法删除行。< / p>

这就是我的意思:

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

答案 1 :(得分:0)

您是将数据显示为只读还是编辑?

如果您允许用户进行编辑,您是否可以找到隐藏不想显示的行的方法,而不是尝试删除它们?

如果您将其显示为只读,则可以在过滤后获取数据,并将其投入新的datagridview ....(丑陋,是的,但可能是一种选择)

哦等等......如果您按值而不是引用传递datagridview,那么删除后的更改是否会保留?