Reputation: 992
I have a List(Of String)
which I want to contain a list of primary keys based on if the associated row in dgv
is displayed.
I need to both add and remove values from the list as they are displayed/hidden.
Currently I am doing this:
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
However this will just add an item to my list when a new row is displayed without removing the hidden row's primary keys.
I can remove a value from the list using VisibleRows.Remove(e.Row.Cells("SQ").Value.ToString)
however I don't know how to identify that a row is no longer displayed.
What is the result of e.StateChanged when a row is no longer displayed?
Upvotes: 0
Views: 537
Reputation: 3905
Hmmm.
DataGridViewElementStates
is an enum containing flags. You might want to check for it like this:
If e.StateChanged And DataGridViewElementStates.Displayed = DataGridViewElementStates.Displayed Then
...
End If
I don't know if the event gets triggered for rows that become invisible. But then again, I would not want to keep track of such a list of strings. Smells not so well.
Personally (if I really need a list of strings containing the visible items), I would do the following:
dgv_RowStateChanged
event handler (or perhaps in a more appropriate event handler; I would need to check)Something like this:
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
But it still does not smell right. Depending on the rest of your code, this might also have a dramatically bad performance.
Edit:
You might replace the For-loop in the VisibleRows
property with the following code:
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
This might be faster...
Edit 2:
The code in my first edit has a bug: you might get an index-out-of-range-exception when you scroll down to the bottom of the datagrid. So you also need to check inside the While-loop if the increased index
value is valid before you try to fetch that next row
or exit the loop otherwise. But I'm not going to correct this. I don't like this entire "solution" at all. ;)
Upvotes: 1