Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Grid.ViewInfo

Public Class ClassDragDrop
    Private downHitInfo As GridHitInfo = Nothing

    Public Sub New()
    End Sub

    Public Sub AddGridView(view As GridView)
        AddHandler view.MouseDown, AddressOf view_MouseDown
        AddHandler view.MouseMove, AddressOf view_MouseMove
        AddHandler view.GridControl.DragOver, AddressOf grid_DragOver
    End Sub

    Private Sub view_MouseDown(sender As Object, e As MouseEventArgs)
        Dim view As GridView = sender
        downHitInfo = Nothing
        Dim hitInfo As GridHitInfo = view.CalcHitInfo(New Point(e.X, e.Y))

        If Control.ModifierKeys <> Keys.None Then
            Return
        End If

        If e.Button = MouseButtons.Left And hitInfo.RowHandle >= 0 Then
            downHitInfo = hitInfo
        End If
    End Sub

    Private Sub view_MouseMove(sender As Object, e As MouseEventArgs)
        Dim view As GridView = sender
        Dim hitInfo As GridHitInfo = view.CalcHitInfo(New Point(e.X, e.Y))

        If e.Button = MouseButtons.Left And Not IsNothing(downHitInfo) Then
            Dim dragSize As Size = SystemInformation.DragSize
            Dim dragRect As New Rectangle(New Point(downHitInfo.HitPoint.X - dragSize.Width / 2, downHitInfo.HitPoint.Y - dragSize.Height / 2), dragSize)

            ' DragRect ist ein kleines Rechteck, dessen Mitte der Punkt ist, wo die Maus geklickt wurde.
            ' Es soll verhindern, dass durch schnelles Klicken unbeabsichtigt Drag'n'Drop Operationen initiiert werden
            ' Siehe: https://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.dragsize(v=vs.110).aspx
            If Not dragRect.Contains(New Point(e.X, e.Y)) Then
                ' dragDropData enhält eine einzelne Row oder den kompletten View,
                ' jenachdem, wie die Drag'n'Drop Operation gestartet wurde.
                Dim dragDropData As Object

                ' Wenn keine Zeile markiert ist
                If downHitInfo.RowHandle < 0 Then
                    Exit Sub
                End If

                ' Wenn zwar eine Zeile markiert ist, aber keine über die Checkbox angehakt wurde,
                ' wird die markierte Zeile übergeben.
                ' Wenn 1 oder n Zeilen über die Checkbox angehakt wurde, werden diese übergeben
                If view.GetSelectedRows().Length = 0 Then
                    Dim row As DataRow = view.GetDataRow(downHitInfo.RowHandle)
                    dragDropData = row
                Else
                    dragDropData = view
                End If

                view.GridControl.DoDragDrop(dragDropData, DragDropEffects.Move)
                downHitInfo = Nothing

                DevExpress.Utils.DXMouseEventArgs.GetMouseArgs(e).Handled = True
            End If
        End If
    End Sub

    Private Sub grid_DragOver(sender As Object, e As DragEventArgs)
        Dim multipleDropped As Boolean = e.Data.GetDataPresent(GetType(GridView))
        Dim singleDroppped As Boolean = e.Data.GetDataPresent(GetType(DataRow))

        ' TODO: Check which kind of record was dragged
        'Dim singleUserDropped As Boolean = e.Data.GetDataPresent(GetType(TBDD_USERRow))
        'Dim singleGroupDropped As Boolean = e.Data.GetDataPresent(GetType(DS_ChangeS.TBDD_GROUPSRow))

        'If multipleDropped Or singleUserDropped Or singleGroupDropped Then
        If multipleDropped Or singleDroppped Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub
End Class