none
Delete Selected Rows from Datagridview

    Question


  • I have a datagridview that is bound to a dataset. I would like to allow the user to select multiple rows and then, when a button is clicked, delete them. I need to populate a second dataset which contains the deleted rows, to pass back to the db. Here's the code I have so far:

           Dim dgvRow As DataGridViewRow
            Dim dsDelete As New DataSet
            dsDelete = dsRefund.Clone
                  For Each dgvRow In dgvRefundData.SelectedRows
                                 dsDelete.Tables(0).ImportRow(dsRefund.Tables(0).Rows(dgvRow.Index))
                                 dsRefund.Tables(0).Rows.RemoveAt(dgvRow.Index)
                End If
            Next

    This works fine but if the dgv is sorted (clicking on column header) the index is wrong. Is there a work around for this? Thanks
    Tuesday, December 18, 2007 3:44 PM

Answers

  • Gotcha.  Try this example that illustrates drilling down into the underlying row from the datasource...

     

    Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim t As New DataTable

    t.Columns.Add("Col1", GetType(String))

    For x As Int32 = 1 To 10

    Dim nr As DataRow = t.NewRow

    nr(0) = x

    t.Rows.Add(nr)

    Next

    DataGridView1.DataSource = t

    End Sub

    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter

    Dim row As DataRow = DirectCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView).Row

    MessageBox.Show("DGV index = " & e.RowIndex & vbCrLf & "Underlying table row index = " & row.Table.Rows.IndexOf(row))

    End Sub

    End Class

     

    Tuesday, December 18, 2007 7:36 PM

All replies

  • I can think of a few ways around this.  First though, it is confusing to me how when the user sorts by a column that the selected rows all stay at the same index in the DGV.  Either all the selected rows are reselected in their new position or just the last selected row is re-selected -- in the new position.  The user should be able to see where the selected rows are at any time and should not click to delete if they look wrong.

     

    But lets just say that your selected rows are not where you or the user expect them to be.  You could add a checkbox column that allows the user to select the rows for deleting (like some online email apps).  The column does not need to be bound but you might want to insert it at the first column index.

     

    Second, you could allow users to delete rows from the gridview and then populate the dsDeleted dataset with the GetChanges rows from the grid's source table (filtering for only those that have a rowstate of Deleted/Removed (whatever the state is called).

     

    Tuesday, December 18, 2007 6:31 PM
  • Thanks (again) for the reply Dig, couple things. I'm not really sure that adding a checkbox field is really going to solve this particular problem. Also, if I select a few rows and then click on the 'sort' column, the selection is lost. This isn't really a problem since I figured the user would sort the rows and then select those they wish to delete.

    I think the basic issue is that the datagridview and the dataset are becoming out of sync after the sort. Notice how I'm referencing the dgv selected row's index to find the appropriate row in the dataset. When the rows are sorted this index has changed. I would have thought that since it is bound the references would change as well, but apparently this isn't the case. Which would explain why the code works before the sort but not after it ( well, it technically works, but it removes the wrong rows)

    I need to remove the row from the dataset which is bound to the dgv and then add that row to dsDelete.
    Tuesday, December 18, 2007 7:24 PM
  • Gotcha.  Try this example that illustrates drilling down into the underlying row from the datasource...

     

    Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim t As New DataTable

    t.Columns.Add("Col1", GetType(String))

    For x As Int32 = 1 To 10

    Dim nr As DataRow = t.NewRow

    nr(0) = x

    t.Rows.Add(nr)

    Next

    DataGridView1.DataSource = t

    End Sub

    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter

    Dim row As DataRow = DirectCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView).Row

    MessageBox.Show("DGV index = " & e.RowIndex & vbCrLf & "Underlying table row index = " & row.Table.Rows.IndexOf(row))

    End Sub

    End Class

     

    Tuesday, December 18, 2007 7:36 PM
  • Ok this code works finr on a cell enter event...can't get it to work on a seleted list of rows....

    The user is allowed to select single or multiple rows from the Datagridview and hit the delete button...


    How do i get the underlying row from the seleted collection of datagridview rows????
    Thursday, July 24, 2008 12:55 PM
  • The code I use in theell-level event can be used on a collection of rows (i.e. SelectedRows) -- you just have to set my Row variable into a loop for the SelectedRows collection.  If you are deleting rows though I'd be careful because you need to delete from the highest-indexed row down to the lowest or else you will be altering the collection mid-loop and likely delete the wrong rows in the process.
    Thursday, July 24, 2008 4:02 PM
  • it's simple...don't use the index (removeAt) use the object(remove)!

    If dgvSelectedUser.SelectedRows.Count > 0 Then

                For i As Integer = dgvSelectedUser.SelectedRows.Count - 1 To 0 Step -1
                    dgvSelectedUser.Rows.Remove(dgvSelectedUser.SelectedRows(i))
                Next

                 End If
    Thursday, July 24, 2008 4:31 PM
  • it's simple...don't use the index (removeAt) use the object(remove)!

    If dgvSelectedUser.SelectedRows.Count > 0 Then

                For i As Integer = dgvSelectedUser.SelectedRows.Count - 1 To 0 Step -1
                    dgvSelectedUser.Rows.Remove(dgvSelectedUser.SelectedRows(i))
                Next

                 End If


    ok and after remove them how can save that to database ?

    coz this code just remove them till I refresh dgv

    Monday, August 22, 2011 3:10 PM