向上或向下稍微复杂一点的DataGridView行,多选 [英] Move up or down little complex DataGridView rows with multi-selection

查看:197
本文介绍了向上或向下稍微复杂一点的DataGridView行,多选的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样一个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问题:

  1. 选择两行在一起(如行索引2和行索引3,不能行索引2和行指数4)

  2. 尝试将行向上的方向。

我怎么能解决呢?

 公共枚举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:

  1. Select two rows that are together (eg. row index 2 and row index 3, NOT row index 2 and row index 4)

  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆