vb.net

Reordering a datagridview on cell value change


I am currently having issues when trying to reorder a datagridview after a cell value has changed. After a value in a specific column has changed I want to resort the columns based on this new value. However it is not quite sorting correctly.

For example, let's say I am starting with the datagridview as shown here:

enter image description here

I then make a change to the Line column of the first row and renumber it to 8. At this point, I would like to move row 1 to where the current row 8 is and every other row would then be renumbered.

I have implemented the following code to do this:

    Dim OuterSourceRowIndex As Integer
    Dim InnerSourceRowIndex As Integer

    If e.ColumnIndex = 0 Then
        For Each rowOuter As DataGridViewRow In dgvReceive.Rows
            For Each rowInner As DataGridViewRow In dgvReceive.Rows
                OuterSourceRowIndex = rowOuter.Index
                InnerSourceRowIndex = rowInner.Index
                If rowOuter.Cells(0).Value >= rowInner.Cells(0).Value Then
                    dgvReceive.Rows.RemoveAt(OuterSourceRowIndex)
                    dgvReceive.Rows.Insert(InnerSourceRowIndex, rowOuter)
                End If
            Next
        Next

        For Each row As DataGridViewRow In dgvReceive.Rows
            row.Cells(0).Value = row.Index + 1
        Next
    End If

When I attempt to actually make the change though I end up with the following where line 1 is actually moved to position 7. All of this is happening on the CellValueChanged event:

enter image description here

I apologize if this has been answered before. I was not able to find anything that was quite like this. Thank you for any help given.


Solution

  • You have probably made this more complicated with those double loops. Also, you should avoid a For-Each loop since you are modifying the collection as you loop over it.

    Not much on error checking, but this is a simplified version. It removes the row you changed, inserts it in the proper place, and then renumbers everything.

    If e.ColumnIndex = 0 Then
      RemoveHandler dgvReceive.CellValueChanged, AddressOf dgvReceive_CellValueChanged
      Dim thisRow As DataGridViewRow = dgvReceive.Rows(e.RowIndex)
      dgvReceive.Rows.Remove(thisRow)
      dgvReceive.Rows.Insert(CInt(thisRow.Cells(0).Value) - 1, thisRow)
      For Each row As DataGridViewRow In dgvReceive.Rows
        row.Cells(0).Value = row.Index + 1
      Next
      AddHandler dgvReceive.CellValueChanged, AddressOf dgvReceive_CellValueChanged
    End If
    

    I added the RemoveHandler and AddHandler lines to prevent too many fireworks from firing when you change all those cell values when you renumber the line items.