Click here to Skip to main content
15,887,304 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everyone, I have an unpredicted behavior from a datatable bound datagridview control and perhaps someone can solve the mystery for me. I have a DataGridView control that is set to:
AllowUserToAddRows=False
AllowUserToDeleteRows=False
SelectionMode=FullRowSelect
I have a button that deletes the selected row and the code for the button is below. The objective is to delete the selected row and select the one under the deleted row unless the deleted row was the last row and in that case it should select the previous row which has now become the last row.
It works as expected except when the selected row is the last row and the line
DGV.CurrentCell = DGV(0, DGV.Rows.Count - 1)
is executed. In that case, it does not select the last row and DGV.SelectedRows.Count becomes 0. To be clear, there are many rows in the grid. It just does not select the newly shown last row when the last row is deleted.

I worked around the issue using the second codeblock posted here where I first select the previous row and then delete the row that was selected. It works as expected but I was trying to understand if there is some kind of "refresh" that needs to be done when using "RemoveAt". By the way, DGV.Refresh() and DGV.Update() seem to have little or no effect when used in this case. When I use DGV.Refresh() right after the 'RemoveAt' sometimes it works as expected but very seldom. So seldom that I cannot say with certainty that Refresh() is making any difference. I even tried putting DGV.CurrentCell=DGV(0, DGV.Rows.Count - 1), Refresh, Update and DoEvents() in a loop until the DGV.SelectedRows.Count>0 and I end up in an infinite loop. (See 'What I have tried:')


Non-Working Code
Private Sub BTNDelete_Click(sender As Object, e As EventArgs) Handles BTNDelete.Click
    Dim CurrentIndex As Integer = DGV.SelectedRows(0).Index
    DGV.Rows.RemoveAt(CurrentIndex)
    If CurrentIndex <= DGV.Rows.Count - 1 Then
         DGV.CurrentCell = DGV(0, CurrentIndex)
    Else
        DGV.CurrentCell = DGV(0, DGV.Rows.Count - 1)
    End If
End Sub


Working Code
Private Sub BTNDelete_Click(sender As Object, e As EventArgs) Handles BTNDelete.Click
    If DGV.SelectedRows.Count > 0 Then
        Dim CurrentIndex As Integer = DGV.SelectedRows(0).Index
        If CurrentIndex = 0 Then
            DGV.CurrentCell = DGV(0, 0)
        Else
            DGV.CurrentCell = DGV(0, CurrentIndex - 1)
        End If
        DGV.Rows.RemoveAt(CurrentIndex)
    End If
End Sub


What I have tried:

DGV.Rows.RemoveAt(CurrentIndex)
While DGV.SelectedRows.Count = 0
    DGV.CurrentCell = DGV(0, DGV.Rows.Count - 1)
    DGV.Refresh()
    DGV.Update()
    Application.DoEvents()
End While
Posted
Updated 26-Dec-20 15:55pm
v4

1 solution

If you delete a "selected row", the selected index goes to -1; there is no default item / row it goes to; you have to select which row you want to be the (next) "selected row"; then worry about any cell, because there is no "current" cell either.

So, prior to deleting a row, get it's index and use that to reposition if it's LESS than the record count. If it's not, and record count is > 0, then set the index to (record count - 1). Setting the index fires the selection changed event.
 
Share this answer
 
Comments
GreekGuy 29-Dec-20 21:17pm    
I was under the impression that Setting DGV.CurrentCell = DGV(ColIndex, RowIndex) does select the row and a specific cell. It works that way in every other case I use it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900