TelerikDeveloper.com

TelerikDeveloper.com

sgray128 8/3/2016 2:53:41 PM

Drag and Drop

This is the code necessary to allow a winforms rad grid to handle dragging and dropping. It's basically a copy of the Telerik documentation but it makes me happy to have it here, and my code is a little more concise

 



Add these two classes to your project.

'initiates drag and drop service for clicked rows
Imports Telerik.WinControls.UI
 
Public Class RowSelectionGridBehavior
    Inherits GridDataRowBehavior
    Protected Overrides Function OnMouseDownLeft(ByVal e As MouseEventArgs) As Boolean
        Dim row As GridDataRowElement = TryCast(Me.GetRowAtPoint(e.Location), GridDataRowElement)
        If Not row Is Nothing Then
            Dim svc As RadGridViewDragDropService = Me.GridViewElement.GetService(Of RadGridViewDragDropService)()
            svc.AllowAutoScrollColumnsWhileDragging = False
            svc.AllowAutoScrollRowsWhileDragging = False
            svc.Start(row)
        End If
        Return MyBase.OnMouseDownLeft(e)
    End Function
End Class
Imports Telerik.WinControls
Imports Telerik.WinControls.UI
 
Public Class DragAndDropGrid
    Inherits RadGridView
 
    Public Sub New()
        Me.MultiSelect = True
        'handle drag and drop events for the grid through the DragDrop service
        Dim svc As RadDragDropService = Me.GridViewElement.GetService(Of RadDragDropService)()
        AddHandler svc.PreviewDragStart, AddressOf svc_PreviewDragStart
        AddHandler svc.PreviewDragDrop, AddressOf svc_PreviewDragDrop
        AddHandler svc.PreviewDragOver, AddressOf svc_PreviewDragOver
        'register the custom row selection behavior
        Dim gridBehavior = TryCast(Me.GridBehavior, BaseGridBehavior)
        gridBehavior.UnregisterBehavior(GetType(GridViewDataRowInfo))
        gridBehavior.RegisterBehavior(GetType(GridViewDataRowInfo), New RowSelectionGridBehavior())
    End Sub
    Public Overrides Property ThemeClassName As String
        Get
            Return GetType(RadGridView).FullName
        End Get
        Set(value As String)
            MyBase.ThemeClassName = value
        End Set
    End Property
    'required to initiate drag and drop when grid is in bound mode
    Private Sub svc_PreviewDragStart(ByVal sender As Object, ByVal e As PreviewDragStartEventArgs)
        e.CanStart = True
    End Sub
    Private Sub svc_PreviewDragOver(ByVal sender As Object, ByVal e As RadDragOverEventArgs)
        If TypeOf e.DragInstance Is GridDataRowElement Then
            e.CanDrop = TypeOf e.HitTarget Is GridDataRowElement OrElse
                    TypeOf e.HitTarget Is GridTableElement OrElse
                    TypeOf e.HitTarget Is GridSummaryRowElement
        End If
    End Sub
    'gather drag/source grid and target/destination information and initiate the move of selected rows
    Private Sub svc_PreviewDragDrop(ByVal sender As Object, ByVal e As RadDropEventArgs)
        Dim rowElement = TryCast(e.DragInstance, GridDataRowElement)
        If rowElement Is Nothing Then
            Return
        End If
        e.Handled = True
        Dim dropTarget = TryCast(e.HitTarget, RadItem)
        Dim targetGrid = TryCast(dropTarget.ElementTree.Control, RadGridView)
        If targetGrid Is Nothing Then
            Return
        End If
        Dim dragGrid = TryCast(rowElement.ElementTree.Control, RadGridView)
        If Not targetGrid Is dragGrid Then
            e.Handled = True
            'append dragged rows to the end of the target grid
            Dim index As Integer = targetGrid.RowCount
            'Grab every selected row from the source grid, including the current row
            Dim rows As New List(Of GridViewRowInfo)
            For Each row As GridViewRowInfo In dragGrid.SelectedRows
                rows.Add(row)
            Next
            If Not dragGrid.CurrentRow Is Nothing Then
                Dim row As GridViewRowInfo = dragGrid.CurrentRow
                If (Not rows.Contains(row)) Then
                    rows.Add(row)
                End If
            End If
            Me.MoveRows(targetGrid, dragGrid, rows, index)
        End If
    End Sub
 
    Private Sub MoveRows(ByVal targetGrid As RadGridView, ByVal dragGrid As RadGridView, ByVal dragRows As IList(Of GridViewRowInfo), ByVal index As Integer)
        Dim strError As String = ""
        'strError = String.Format("Param: {0}",Param)
        Try
 
            dragGrid.BeginUpdate()
            targetGrid.BeginUpdate()
            Dim frmInboundFreightLoad As InboundFreightLoad = CType(targetGrid.Parent, InboundFreightLoad)
            Dim frmInboundFreightRequested As InboundFreightRequested = CType(dragGrid.Parent, InboundFreightRequested)
            Dim strTargetPlant As String = frmInboundFreightLoad.txtPlant.Text
            Dim strTruckPO As String = frmInboundFreightLoad.txtTruckPO.Text
 
            If strTargetPlant = "" Then
                Common.globalmessagebox("Cannot accept, the target form must be populated")
                Exit Sub
            End If
 
            For i As Integer = dragRows.Count - 1 To 0 Step -1
                Dim oRow As GridViewRowInfo = dragRows(i)
                If TypeOf oRow Is GridViewSummaryRowInfo Then
                    Continue For
                End If
 
                'be sure that drug line matches the plant on the target form
                Dim strSourcePlant As String = oRow.Cells("itmgedsc").Value
 
                If strTargetPlant <> strSourcePlant Then
                    Common.globalmessagebox("Cannot accept, only one plant allowed on a Truck PO")
                    Exit Sub
                End If
 
 
                Dim strSopnumbe As String = oRow.Cells("sopnumbe").Value
                Dim strItemNumber As String = oRow.Cells("itemnmbr").Value.ToString.Trim
                Dim intSoptype As Int32 = oRow.Cells("soptype").Value
                Dim intLineItemSeq As Int32 = oRow.Cells("lnitmseq").Value
 
                'deletes then recreates the SOR
                SPs.FP_SOP10200_RecordPOReservation(strSopnumbe, intSoptype, intLineItemSeq, App.Database).execute()
 
                Dim oDT3 As DataTable = SPs.FP_POP10110SOR_SEL_byID(strSopnumbe, intSoptype, intLineItemSeq, App.Database).getTable
                If oDT3.Rows.Count = 0 Then
                    Common.globalmessagebox("Error reserving {0} against a PO. Please contact an administrator", strItemNumber)
                    Exit Sub
                End If
 
                Dim strPickup As String = "" 'oDT3.Rows(0)("pickup")
                SPs.FP_FPTruckPODetail_Merge(0, strTruckPO, strSopnumbe, intSoptype, intLineItemSeq, strItemNumber, oRow.Cells("UofM").Value,
                                         CDec(oRow.Cells("quantity").Value), strPickup, oRow.Cells("Locncode").Value, "", App.Database).execute()
 
 
                frmInboundFreightLoad.bindgrid()
                frmInboundFreightRequested.bindgrid()
 
                index += 1
            Next i
            dragGrid.EndUpdate(True)
            targetGrid.EndUpdate(True)
        Catch ex As Exception
            ErrorHandler.globalErrorHandler(ex, strError, True)
        End Try
    End Sub
End Class

Compile the project, and you should have a new tool in the toolbox:

Drag two of these grids onto two forms.

All the work is done in the 'MoveRow' method. The Telerik sample code assumes the grids have the same columns and copies from one to another. My code handles the changes at a database level and then refreshes both grids.