我有一个List(Of String)
,我想根据显示的是dgv
中的相关行来包含主键列表。
我需要在显示/隐藏值时从列表中添加和删除值。
目前我正在这样做:
Private Sub dgv_RowStateChanged(sender As Object, e As DataGridViewRowStateChangedEventArgs) Handles dgv.RowStateChanged
If e.StateChanged = DataGridViewElementStates.Displayed Then
If Not VisibleRows.Contains(e.Row.Cells("SQ").Value.ToString) Then
VisibleRows.Add(e.Row.Cells("SQ").Value.ToString)
End If
End If
End Sub
但是,这只会在显示新行时将项目添加到我的列表中,而不会删除隐藏行的主键。
我可以使用VisibleRows.Remove(e.Row.Cells("SQ").Value.ToString)
从列表中删除一个值,但是我不知道如何识别不再显示行。
不再显示行时e.StateChanged的结果是什么?
答案 0 :(得分:1)
嗯。
DataGridViewElementStates
是一个包含标志的枚举。您可能要像这样检查它:
If e.StateChanged And DataGridViewElementStates.Displayed = DataGridViewElementStates.Displayed Then
...
End If
我不知道是否为不可见的行触发了该事件。但是话又说回来,我不想跟踪这样的字符串列表。闻起来不太舒服。
个人(如果我真的需要包含可见项的字符串列表),我将执行以下操作:
dgv_RowStateChanged
事件处理程序中(或可能在更合适的事件处理程序中,使列表无效(或简单处理); 类似这样的东西:
Private _visibleRows As List(Of String) 'Only use this inside the VisibleRows property and the dgv_RowStateChanged event handler. For all other usage of the list, use the VisibleRows property!
Private ReadOnly Property VisibleRows As List(Of String)
Get
If _visibleRows Is Nothing Then
_visibleRows = New List(Of String)
For Each row As DataGridViewRow In dgv.Rows
If row.Displayed Then
_visibleRows.Add(row.Cells("SQ").Value.ToString)
End If
Next
End If
Return _visibleRows
End Get
End Property
Private Sub dgv_RowStateChanged(sender As Object, e As DataGridViewRowStateChangedEventArgs) Handles dgv.RowStateChanged
_visibleRows = Nothing
End Sub
但是它仍然闻不到正确的气味。根据代码的其余部分,这也可能会导致性能严重下降。
编辑:
您可以使用以下代码替换VisibleRows
属性中的For循环:
Dim index As Integer = dgv.FirstDisplayedScrollingRowIndex
Dim row = dgv.Rows(index)
While (row.Displayed)
_visibleRows.Add(row.Cells("SQ").Value.ToString)
index += 1
row = dgv.Rows(index)
End While
这可能会更快...
编辑2:
我的第一次编辑中的代码有一个错误:向下滚动到数据网格的底部时,可能会出现索引超出范围的异常。因此,在尝试获取下一个index
之前,还需要在While循环内部检查是否增大的row
值是有效的,否则,请退出循环。但是我不会纠正这个问题。我根本不喜欢整个“解决方案”。 ;)