5

Windowsアプリ(Visual Studio)(VB)で、ユーザーが行を並べ替えられるように、1つの行を別の位置にドラッグアンドドロップするにはどうすればよいですか?これにふさわしい例はまだ見つかりません。

4

5 に答える 5

8

このC#の回答からのvbバージョンは次のとおりです。DataGridView行を相互にドラッグアンドドロップするにはどうすればよいですか?

フォームクラス変数:

Private fromIndex As Integer
Private dragIndex As Integer
Private dragRect As Rectangle

ドラッグイベント:

Private Sub DataGridView1_DragDrop(ByVal sender As Object, _
                                   ByVal e As DragEventArgs) _
                                   Handles DataGridView1.DragDrop
  Dim p As Point = DataGridView1.PointToClient(New Point(e.X, e.Y))
  dragIndex = DataGridView1.HitTest(p.X, p.Y).RowIndex
  If (e.Effect = DragDropEffects.Move) Then
    Dim dragRow As DataGridViewRow = e.Data.GetData(GetType(DataGridViewRow))
    DataGridView1.Rows.RemoveAt(fromIndex)
    DataGridView1.Rows.Insert(dragIndex, dragRow)
  End If
End Sub

Private Sub DataGridView1_DragOver(ByVal sender As Object, _
                                   ByVal e As DragEventArgs) _
                                   Handles DataGridView1.DragOver
  e.Effect = DragDropEffects.Move
End Sub

マウスイベント:

Private Sub DataGridView1_MouseDown(ByVal sender As Object, _
                                    ByVal e As MouseEventArgs) _
                                    Handles DataGridView1.MouseDown
  fromIndex = DataGridView1.HitTest(e.X, e.Y).RowIndex
  If fromIndex > -1 Then
    Dim dragSize As Size = SystemInformation.DragSize
    dragRect = New Rectangle(New Point(e.X - (dragSize.Width / 2), _
                                       e.Y - (dragSize.Height / 2)), _
                             dragSize)
  Else
    dragRect = Rectangle.Empty
  End If
End Sub

Private Sub DataGridView1_MouseMove(ByVal sender As Object, _
                                    ByVal e As MouseEventArgs) _
                                    Handles DataGridView1.MouseMove
  If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
    If (dragRect <> Rectangle.Empty _
    AndAlso Not dragRect.Contains(e.X, e.Y)) Then
      DataGridView1.DoDragDrop(DataGridView1.Rows(fromIndex), _
                               DragDropEffects.Move)
    End If
  End If
End Sub

gridsAllowDropプロパティがtrueに設定されていることを確認してください。

于 2012-07-19T20:50:11.103 に答える
4

アップデート:

それ以外の

 If dragIndex < 0 Then dragIndex = DataGridView1.RowCount - 1

への変更

 If dragIndex > -1 Then 
      'action if not selected in the row header and blank space
 else
      'return error if selected in the column header and blank space
 end if

次に、行を「空白ゾーン」にドラッグするとエラーが発生します。私を信じていない場合は、試してみる必要があります。

最終的なコード(「ドラッグイベント」の部分のみ)は次のとおりです。

  Private Sub DataGridView1_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragDrop
        Dim p As Point = DataGridView1.PointToClient(New Point(e.X, e.Y))
        dragIndex = DataGridView1.HitTest(p.X, p.Y).RowIndex
    'Determine if dragindex is valid row index       
    If dragIndex > -1 Then
        If (e.Effect = DragDropEffects.Move) Then
            Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow)
            DataGridView1.Rows.RemoveAt(fromIndex)
            DataGridView1.Rows.Insert(dragIndex, dragRow)
            'Add this line of code if you want to put selected rows to the rows that change
            DataGridView1.Rows(dragIndex).Selected = True
        End If 
       Else 'Do any message here if selected in column header and blank space. 
       End If
    End Sub
于 2014-05-11T06:47:10.013 に答える
1

これが、前述のバグのないコントロールです。

WindowsフォームデザイナでAllowUserToOrderRowsAllowDropを設定し、コンテンツではなく行ヘッダーをドラッグします。True

Imports System.ComponentModel

Public Class BetterDataGridView
    Inherits DataGridView

    <Category("Behavior"), DefaultValue(False)>
    Public Property AllowUserToOrderRows As Boolean = False

    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        MyBase.OnMouseDown(e)

        Dim hitInfo As HitTestInfo = HitTest(e.X, e.Y)
        If AllowUserToOrderRows AndAlso
                e.Button = MouseButtons.Left AndAlso
                hitInfo.ColumnIndex = -1 AndAlso
                ValidRow(hitInfo.RowIndex) Then
            DoDragDrop(Rows(hitInfo.RowIndex), DragDropEffects.Move)
        End If
    End Sub

    Protected Overrides Sub OnDragOver(e As DragEventArgs)
        MyBase.OnDragOver(e)

        Dim dragRow As DataGridViewRow = e.Data.GetData(GetType(DataGridViewRow))
        Dim targetIndex As Integer = GetRowIndex(e)
        e.Effect = If(ValidRowDragDrop(dragRow, targetIndex),
                      DragDropEffects.Move,
                      DragDropEffects.None)
    End Sub

    Protected Overrides Sub OnDragDrop(e As DragEventArgs)
        MyBase.OnDragDrop(e)

        Dim dragRow As DataGridViewRow = e.Data.GetData(GetType(DataGridViewRow))
        Dim targetIndex As Integer = GetRowIndex(e)

        If e.Effect = DragDropEffects.Move AndAlso ValidRowDragDrop(dragRow, targetIndex) Then
            EndEdit()

            Rows.Remove(dragRow)
            Rows.Insert(targetIndex, dragRow)

            ClearSelection()
            dragRow.Selected = True
        End If
    End Sub

    Protected Function ValidRow(rowIndex As Integer) As Boolean
        Return rowIndex >= 0 AndAlso
            rowIndex < Rows.Count - If(AllowUserToAddRows, 1, 0)
    End Function

    Protected Function GetRowIndex(e As DragEventArgs) As Integer
        Dim clientPos As Point = PointToClient(New Point(e.X, e.Y))
        Return HitTest(clientPos.X, clientPos.Y).RowIndex
    End Function

    Protected Function ValidRowDragDrop(dragRow As DataGridViewRow, targetIndex As Integer) As Boolean
        Return dragRow IsNot Nothing AndAlso
            ValidRow(targetIndex) AndAlso
            targetIndex <> dragRow.Index AndAlso
            Rows.Contains(dragRow)
    End Function
End Class
于 2016-09-30T20:16:36.310 に答える
1

イベントGridView.DragDropの1.5の改善:

  1. 最初の50%の改善、説明されたエラーを回避するために、次を使用することもできます

    Private Sub DgvSearchFieldCurrent_DragDrop( _
       ByVal sender As  Object, ByVal e As DragEventArgs) _
       Handles DgvSearchFieldCurrent.DragDrop
    
    Dim LclDgv As DataGridView = CType(sender, DataGridView)
    
    If dragIndex > -1 AndAlso dragIndex < LclDgv.RowCount -1 Then
    
  2. 2つ目は、現在の行と最初のセルにフォーカスを設定することです。

    LclDgv.Rows.Insert(dragIndex, dragRow)
    
    LclDgv.Rows(fromIndex).Selected = False
    LclDgv.Rows(dragIndex).Selected = True
    
    For Each C As DataGridViewColumn In LclDgv.Columns
      LclDgv(C.Index, fromIndex).Selected = False
    Next
    
    LclDgv(0, dragIndex).Selected = True
    
于 2017-06-27T13:25:56.183 に答える
0

コードが機能しているすべてに感謝します。エラーが1つだけ発生しました。私はそれを解決しました。

datagridviewの「編集を有効にする」が設定されている場合、行間隔をスローするとエラーが発生します。あなたが試すことができます。私はそれを次のように解決しました:

    Private Sub DataGridView1(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragDrop

    Dim p As Point = DataGridView1.PointToClient(New Point(e.X, e.Y))
                    dragIndex = DataGridView1.HitTest(p.X, p.Y).RowIndex
                    If (e.Effect = DragDropEffects.Move) Then
                        Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow)

                        If dragIndex = DataGridView1.RowCount - 1 Then '**ADD THIS AREA**
                            DataGridView1.Rows.RemoveAt(fromIndex)
                            DataGridView1.Rows.Insert(DataGridView1.RowCount - 1, dragRow)
                        Else
                            If dragIndex < 0 Then dragIndex = DataGridView1.RowCount - 2 '**this is important**
                            DataGridView1.Rows.RemoveAt(fromIndex)
                            DataGridView1.Rows.Insert(dragIndex, dragRow)
                        End If
                    End If
End Sub

他のすべての情報をありがとう

于 2015-08-12T16:03:36.290 に答える