我的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
答案 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,那么删除后的更改是否会保留?