向上或向下稍微复杂一点的DataGridView行,多选 [英] Move up or down little complex DataGridView rows with multi-selection
问题描述
我有这样一个DataGridView:
现在,在 C#或其他 VB.Net ,有一个按钮,我想向上或向下移动一个位置选定行,我怎么能做到这一点?。多选择所需的复杂我这一点。
这是出现在DataGridView将合并为一个可执行文件的文件,那么,该文件将在订单列的顺序来执行,因此,订单值应该移动的行向上或向下时要inmutable。
我不使用任何数据源。
我试图分析这个样本从 MSDN ,它包括一些扩展方法,但它需要一个数据表和数据源,我没有任何dissapoint使用数据表和数据源,但只是我不知道如何适应code-样品我的DataGridView。 反正样品不支持多点选择:
移动行向上/向下还记得为了绑定的DataGridView和ListBoxs数据
我也看到的StackOverflow的有关这方面的一些C#的问题,但他们要求单行选择:
<一个href="http://stackoverflow.com/questions/16232943/how-to-move-gridview-selected-row-up-down-on-keyup-or-keydown-$p$pss">How移动GridView的选择行向上/向下的KeyUp或KEYDOWN preSS
<一个href="http://stackoverflow.com/questions/1012708/datagridview-selected-row-move-up-and-down">DataGridView选择行上下移动
然后,我没有一个出发点,只是这些方法来移动一行也没有preserve在订单的价值,如果有人可以指导我来扩展功能我的需求: 私人小组Button_MoveUp_Click(发送者为对象,E作为EventArgs的)_ 把手Button_MoveUp.Click
Me.MoveUpSelectedRows(Me.DataGridView_Files)
结束小组
私人小组Button_MoveDown_Click(发送者为对象,E作为EventArgs的)_
手柄Button_MoveDown.Click
Me.MoveDownSelectedRows(Me.DataGridView_Files)
结束小组
私人小组MoveUpSelectedRows(BYVAL DGV至于DataGridView中)
昏暗curRowIndex作为整数= dgv.CurrentCell.RowIndex
昏暗newRowIndex作为整数= curRowIndex - 1
昏暗curColIndex作为整数= dgv.CurrentCell.ColumnIndex
昏暗curRow作为的DataGridViewRow = dgv.CurrentRow
如果(dgv.SelectedCells.Count大于0)AndAlso(newRowIndex&GT; = 0)然后
随着DGV
.Rows.Remove(curRow)
.Rows.Insert(newRowIndex,curRow)
.CurrentCell = DGV(curColIndex,newRowIndex)
结束与
结束如果
结束小组
私人小组MoveDownSelectedRows(BYVAL DGV至于DataGridView中)
昏暗curRowIndex作为整数= dgv.CurrentCell.RowIndex
昏暗newRowIndex作为整数= curRowIndex + 1
昏暗curColIndex作为整数= dgv.CurrentCell.ColumnIndex
昏暗curRow作为的DataGridViewRow = dgv.CurrentRow
如果(dgv.SelectedCells.Count大于0)AndAlso(dgv.Rows.Count&GT; newRowIndex)然后
随着DGV
.Rows.Remove(curRow)
.Rows.Insert(newRowIndex,curRow)
.CurrentCell = DGV(curColIndex,newRowIndex)
结束与
结束如果
结束小组
更新
我想@Plutonix方法(用少许修改),唯一的问题是,它不能正常移动选定行向上的方向。
步骤reprduce问题:
-
选择两行在一起(如行索引2和行索引3,不能行索引2和行指数4)
-
尝试将行向上的方向。
我怎么能解决呢?
公共枚举MoveDirection作为整数
截至= -1
关闭= 1
结束枚举
私人小组MoveRows(BYVAL DGV至于DataGridView中,BYVAL moveDirection作为MoveDirection)
昏暗的行作为DataGridViewRowCollection = dgv.Rows
行索引
昏暗thisRow作为的DataGridViewRow
把选择回
昏暗selectedRows作为新的列表(整数)
最大行数
昏暗lastRowIndex作为整数=
如果(dgv.AllowUserToAddRows,
rows.Count - 2,
rows.Count - 1)
对于n为整数= lastRowIndex 0步骤-1
如果不是行(N).IsNewRow然后
如果行(N).Selected然后
selectedRows.Add(N)
MSGBOX(N)
选择案例moveDirection
案例Main.MoveDirection.Down
如果((N + moveDirection)&LT; = lastRowIndex)AndAlso(N + moveDirection&GT; = 0)AndAlso行(N + moveDirection).Selected = false,那么
selectedRows(selectedRows.Count - 1)=(N + moveDirection)
thisRow =行(N)
rows.Remove(thisRow)
rows.Insert(N + moveDirection,thisRow)
结束如果
案例Main.MoveDirection.Up
如果(第(n + moveDirection)其中; = lastRowIndex)然后
MSGBOX(selectedRows(selectedRows.Count - 1))
selectedRows(selectedRows.Count - 1)=(N + moveDirection)
thisRow =行(N)
rows.Remove(thisRow)
rows.Insert(N + moveDirection,thisRow)
结束如果
最终选择
结束如果
结束如果
下一个N
重新选择原来选定的行
对于n为整数= 0要lastRowIndex
dgv.Rows(N).Selected = selectedRows.Contains(N)
重新编号的顺序(可选&安培;未知的,但平凡)
dgv.Rows(n)的.Cells(0)。价值=第(n + 1)
下一个N
结束小组
(更新)
您需要遍历行集合,如果测试都被选中,然后交换行。为了保持2选定行之间互相交换,当他们到达顶部或底部,一个独立的向上和向下的方法是必要的。
'哈希$ C $选定行的CS名单
专用功能GetSelectedRows()方式列表(整数)
昏暗selR作为新的列表(整数)
'必须明确选择,以便下一行
不导致古怪的行为
对于n为整数= 0要dgv.Rows.Count - 1
如果dgv.Rows(N).IsNewRow =假AndAlso dgv.Rows(N).Selected然后
selR.Add(dgv.Rows(N).GetHash code)
dgv.Rows(N).Selected =假
结束如果
下一个
返回selR
端功能
恢复原来选定的行
私人小组SetSelectedRows(selRows作为列表(整数))
对于n为整数= 0要dgv.Rows.Count - 1
如果dgv.Rows(N).IsNewRow = false,那么
dgv.Rows(N).Selected = selRows.Contains(dgv.Rows(N).GetHash code)
重置次序西:
dgv.Rows(n)的.Cells(0)。价值= n + 1个
结束如果
下一个
结束小组
私人小组MoveRowsUp()
短期参考
昏暗的行作为DataGridViewRowCollection = dgv.Rows
行索引
昏暗thisRow作为的DataGridViewRow
把选择回
昏暗selectedRows方式列表(整数)
最大行数
昏暗LASTROW = IF(dgv.AllowUserToAddRows,rows.Count - 2,rows.Count - 1)
selectedRows = GetSelectedRows()
对于n作为的Int32 = 0至LASTROW
如果行(N).IsNewRow = false,那么
如果(selectedRows.Contains(行(N).GetHash code))AndAlso(N - 1&GT; = 0)AndAlso
(selectedRows.Contains(行(N - 1).GetHash code)= FALSE)然后
thisRow =行(N)
rows.Remove(thisRow)
rows.Insert(N - 1,thisRow)
结束如果
结束如果
下一个
SetSelectedRows(selectedRows)
结束小组
私人小组MoveRowsDn()
昏暗的行作为DataGridViewRowCollection = dgv.Rows
昏暗thisRow作为的DataGridViewRow
昏暗selectedRows作为新的列表(整数)
昏暗LASTROW = IF(dgv.AllowUserToAddRows,rows.Count - 2,rows.Count - 1)
selectedRows = GetSelectedRows()
对于n作为的Int32 = LASTROW 0步骤-1
如果行(N).IsNewRow = false,那么
如果(selectedRows.Contains(行(N).GetHash code))AndAlso(N + 1&LT; = LASTROW)AndAlso
(selectedRows.Contains(行(N + 1).GetHash code)= FALSE)然后
thisRow =行(N)
rows.Remove(thisRow)
rows.Insert第(n + 1,thisRow)
结束如果
结束如果
下一个
SetSelectedRows(selectedRows)
结束小组
用法:
MoveRowsUp()
下移:
MoveRowsDn()
移动的行使DGV重置选择。该方法首先去通,并获得所选行的哈希codeS的列表,然后在结束复位的基础上,每个 Row.Selected
属性。
在code更改单元格的值(0),因此订单和订单列匹配(即顺序列值的是的可变)。
移动检查,看两者是否此行是在最后的或的如果还选择了该行的目的地。这$ P $从交换的地方,当他们到达顶部或底部pvents行。
在:
在:
请注意,当Zalgo到了底部(意思3和5被选择),另一种可能仍然向下移动,所以它确实而齐格留了下来放。 齐格(3)的向下移动与否的能力是基于下一行/索引(只) - 中的下一行是没有超出底部的和的未选中所以它仍然向下移动1,而Zalgo(5)不能。
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
(Updated)
You need to iterate the rows collection, test if each is selected, then swap rows. In order to keep 2 selected rows from swapping with each other when they get to the top or bottom, a separate Up and Down method are needed.
' list of hash codes of the selected rows
Private Function GetSelectedRows() As List(Of Integer)
Dim selR As New List(Of Integer)
' have to clear selected so the NEXT row
' doesnt cause odd behavior
For n As Integer = 0 To dgv.Rows.Count - 1
If dgv.Rows(n).IsNewRow = False AndAlso dgv.Rows(n).Selected Then
selR.Add(dgv.Rows(n).GetHashCode)
dgv.Rows(n).Selected = False
End If
Next
Return selR
End Function
' restore original selected rows
Private Sub SetSelectedRows(selRows As List(Of Integer))
For n As Integer = 0 To dgv.Rows.Count - 1
If dgv.Rows(n).IsNewRow = False Then
dgv.Rows(n).Selected = selRows.Contains(dgv.Rows(n).GetHashCode)
' reset Order col:
dgv.Rows(n).Cells(0).Value = n + 1
End If
Next
End Sub
Private Sub MoveRowsUp()
' short ref
Dim rows As DataGridViewRowCollection = dgv.Rows
' row index
Dim thisRow As DataGridViewRow
' put selection back
Dim selectedRows As List(Of Integer)
' max rows
Dim LastRow = If(dgv.AllowUserToAddRows, rows.Count - 2, rows.Count - 1)
selectedRows = GetSelectedRows()
For n As Int32 = 0 To LastRow
If rows(n).IsNewRow = False Then
If (selectedRows.Contains(rows(n).GetHashCode)) AndAlso (n - 1 >= 0) AndAlso
(selectedRows.Contains(rows(n - 1).GetHashCode) = False) Then
thisRow = rows(n)
rows.Remove(thisRow)
rows.Insert(n - 1, thisRow)
End If
End If
Next
SetSelectedRows(selectedRows)
End Sub
Private Sub MoveRowsDn()
Dim rows As DataGridViewRowCollection = dgv.Rows
Dim thisRow As DataGridViewRow
Dim selectedRows As New List(Of Integer)
Dim LastRow = If(dgv.AllowUserToAddRows, rows.Count - 2, rows.Count - 1)
selectedRows = GetSelectedRows()
For n As Int32 = LastRow To 0 Step -1
If rows(n).IsNewRow = False Then
If (selectedRows.Contains(rows(n).GetHashCode)) AndAlso (n + 1 <= LastRow) AndAlso
(selectedRows.Contains(rows(n + 1).GetHashCode) = False) Then
thisRow = rows(n)
rows.Remove(thisRow)
rows.Insert(n + 1, thisRow)
End If
End If
Next
SetSelectedRows(selectedRows)
End Sub
Usage:
MoveRowsUp()
' move down:
MoveRowsDn()
Moving the rows causes the dgv to reset the selections. The methods first go thru and get a list of the HashCodes of the selected rows, then at the end resets each Row.Selected
property based on that.
The code changes the value of Cell(0) so the order and Order column match (which means the Order column value is mutable).
Moving checks to see both if this row is at the end OR if the row at the destination is also selected. This prevents rows from swapping places when they get to the top or bottom.
Before:
After:
Note that when "Zalgo" got to the bottom (meaning 3 and 5 were selected), the other one could still move down one, so it did while "Ziggy" stayed put. The ability of "Ziggy(3)" to move down or not is based on the next row/index (only) - the next row is not beyond the bottom AND not selected so it can still move down 1, while "Zalgo (5)" could not.
这篇关于向上或向下稍微复杂一点的DataGridView行,多选的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!