I have a DataGridView like this:
Now, In C# or else VB.Net, with a button, I would like to move up or down one position the selected rows, how I could do it?. The multi selection requisite complicate me this.
The files that appear in the DataGridView will be combined into a single executable file, then, the files will be executed in the order of the "Order" column, so the "Order" value should be inmutable when moving rows up or down.
I'm not using any data source.
I've tried to analyze this sample from MSDN, it consists in some extension methods, but it takes a datatable and datasource, I don't have any dissapoint to use a datatable and datasource but just I don't know how to adapt the code-sample for my DataGridView. Anyways the sample does not support multi selection:
Move rows up/down and remember order for DataGridView and ListBoxs data bound
I also have seen some C# questions about this on StackOverflow but they asks for single row selection:
How to move gridview selected row up/down on KeyUp or Keydown press
DataGridView Selected Row Move UP and DOWN
Then, I don't have an starting point, just these methods to move a SINGLE row that also does not preserve the Order value, if someone could guide me to extend the functionality for my needs: Private Sub Button_MoveUp_Click(sender As Object, e As EventArgs) _ Handles Button_MoveUp.Click
Me.MoveUpSelectedRows(Me.DataGridView_Files)
End Sub
Private Sub Button_MoveDown_Click(sender As Object, e As EventArgs) _
Handles Button_MoveDown.Click
Me.MoveDownSelectedRows(Me.DataGridView_Files)
End Sub
Private Sub MoveUpSelectedRows(ByVal dgv As DataGridView)
Dim curRowIndex As Integer = dgv.CurrentCell.RowIndex
Dim newRowIndex As Integer = curRowIndex - 1
Dim curColIndex As Integer = dgv.CurrentCell.ColumnIndex
Dim curRow As DataGridViewRow = dgv.CurrentRow
If (dgv.SelectedCells.Count > 0) AndAlso (newRowIndex >= 0) Then
With dgv
.Rows.Remove(curRow)
.Rows.Insert(newRowIndex, curRow)
.CurrentCell = dgv(curColIndex, newRowIndex)
End With
End If
End Sub
Private Sub MoveDownSelectedRows(ByVal dgv As DataGridView)
Dim curRowIndex As Integer = dgv.CurrentCell.RowIndex
Dim newRowIndex As Integer = curRowIndex + 1
Dim curColIndex As Integer = dgv.CurrentCell.ColumnIndex
Dim curRow As DataGridViewRow = dgv.CurrentRow
If (dgv.SelectedCells.Count > 0) AndAlso (dgv.Rows.Count > newRowIndex) Then
With dgv
.Rows.Remove(curRow)
.Rows.Insert(newRowIndex, curRow)
.CurrentCell = dgv(curColIndex, newRowIndex)
End With
End If
End Sub
UPDATE
I'm trying @Plutonix approach (with a little modification), the only problem is that it does not move properly the selected rows to UP direction.
Steps to reprduce the issue:
Select two rows that are together (eg. row index 2 and row index 3, NOT row index 2 and row index 4)
Try to move the rows to UP direction.
How I could fix it?.
Public Enum MoveDirection As Integer
Up = -1
Down = 1
End Enum
Private Sub MoveRows(ByVal dgv As DataGridView, ByVal moveDirection As MoveDirection)
Dim rows As DataGridViewRowCollection = dgv.Rows
' row index
Dim thisRow As DataGridViewRow
' put selection back
Dim selectedRows As New List(Of Integer)
' max rows
Dim lastRowIndex As Integer =
If(dgv.AllowUserToAddRows,
rows.Count - 2,
rows.Count - 1)
For n As Integer = lastRowIndex To 0 Step -1
If Not rows(n).IsNewRow Then
If rows(n).Selected Then
selectedRows.Add(n)
MsgBox(n)
Select Case moveDirection
Case Main.MoveDirection.Down
If ((n + moveDirection) <= lastRowIndex) AndAlso (n + moveDirection >= 0) AndAlso rows(n + moveDirection).Selected = False Then
selectedRows(selectedRows.Count - 1) = (n + moveDirection)
thisRow = rows(n)
rows.Remove(thisRow)
rows.Insert(n + moveDirection, thisRow)
End If
Case Main.MoveDirection.Up
If ((n + moveDirection) <= lastRowIndex) Then
MsgBox(selectedRows(selectedRows.Count - 1))
selectedRows(selectedRows.Count - 1) = (n + moveDirection)
thisRow = rows(n)
rows.Remove(thisRow)
rows.Insert(n + moveDirection, thisRow)
End If
End Select
End If
End If
Next n
' reselect the original selected rows
For n As Integer = 0 To lastRowIndex
dgv.Rows(n).Selected = selectedRows.Contains(n)
' renumber the order (optional & unknown, but trivial)
dgv.Rows(n).Cells(0).Value = (n + 1)
Next n
End Sub