Problem using dragdrop with datagrid

Posted on 2005-03-31
Medium Priority
Last Modified: 2010-04-24

I have two datagrids that are on a form and i want to drag from one datagrid (1), which is on the right of the screen to the other datagrid (2). which is on the left of the screen

The problem i am getting is that when i drag an item from datagrid (1) and drop it on to datagrid(2).  The hittestinfo givesw me the row and column for datagrid(1) even though i am not dropping on it.

The code to get the hittestinfo is simple:

        Dim hti2 As DataGrid.HitTestInfo
        Dim pt As Point

        pt = New Point(e.X, e.Y)

        Dim myGrid As DataGrid = CType(sender, DataGrid)
        hti2 = myGrid.HitTest(PointToClient(pt))

If you were to imagine a horizontal grid accross the screen, wherever i drop the item on datagrid(2), it gives me the corresponding column and row from datagrid(1) if you were to follow the horizontal line.

Any ideas?

Oh yea, the two datagrids are user controls that inherit the datagrid windows control.
Question by:schott19
LVL 14

Accepted Solution

amyhxu earned 500 total points
ID: 13675080
Here's an example of implementing dragdrop between two datagrids from http://www.syncfusion.com/FAQ/WinForms/  DataGrid Section Q 5.36 :

This sample has a derived datagrid that supports OLE D&D with any OLE D&D provider that handles a Text formatted data object. The derived grid handles six events to allow it to be both a drop source and a drop target. The sample project has two datagrids where you can drag cell text back and forth. You can also open Excel, and drag text between Excel and either datagrid.

Here are the events that are handled in this sample.

MouseDown - Used to save the row and column of a mousedown, 'mousedowncell'.
MouseMove - Checks to see if you drag off the mousedowncell, and if so, starts a the DoDragDrop.
MouseUp - Used to reset the mousedowncell.
DragEnter - Checks to see if the data object has text, and if so, allows a Copy operation. (This could be changed to support Move/Copy.)
DragOver - Used to set a NoDrop cursor if you move over the mousedowncell (if mousedowncell has been set).
DragDrop - Used to drop the text into the datagrid.

Option Strict Off
Option Explicit On

Imports Microsoft.VisualBasic
Imports System
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Windows.Forms

    Public Class Form1
        Inherits Form
        Private WithEvents dataGrid1 As Form1.DnDDataGrid
        Private WithEvents dataGrid2 As Form1.DnDDataGrid
        Private components As Container
        Private WithEvents dt As DataTable
        Private WithEvents dt2 As DataTable
        'Nested Types
        Public Sub New()
            Me.dt = New DataTable("Table1")
            Me.dt2 = New DataTable("Table2")
            ' Required for Windows Form Designer support
            ' TODO: Add any constructor code after InitializeComponent call
            dt.Columns.Add("Int32", Type.GetType("System.String"))
            dt.Columns.Add("Char", Type.GetType("System.String"))
            Dim dr As DataRow
            Dim i As Integer
            i = 0

            Do While (i <= 10)
                dr = dt.NewRow
            dr("Int32") = "text " + i.ToString
            dr("Char") = ChrW(i + 33)
                i = (i + 1)

            dataGrid1.DataSource = dt
            dt2.Columns.Add("Int32", Type.GetType("System.String"))
            dt2.Columns.Add("Char", Type.GetType("System.String"))
            Dim dr1 As DataRow
            i = 0

            Do While (i <= 20)
                dr1 = dt2.NewRow
            dr1("Int32") = "row " + i.ToString
            dr1("Char") = ChrW(i + 33)
                i = (i + 1)

            dataGrid2.DataSource = dt2

        End Sub
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

            If disposing Then
                If (Not (components) Is Nothing) Then
                End If
            End If

        End Sub
        Private Sub InitializeComponent()

            Me.dataGrid1 = New DataGridDnD.Form1.DnDDataGrid()
            Me.dataGrid2 = New DataGridDnD.Form1.DnDDataGrid()
        CType(Me.dataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.dataGrid2, System.ComponentModel.ISupportInitialize).BeginInit()
            ' dataGrid1
            Me.dataGrid1.AllowDrop = True
            Me.dataGrid1.DataMember = ""
            Me.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
            Me.dataGrid1.Location = New System.Drawing.Point(56, 24)
            Me.dataGrid1.Name = "dataGrid1"
            Me.dataGrid1.PreferredColumnWidth = 50
            Me.dataGrid1.Size = New System.Drawing.Size(208, 184)
            Me.dataGrid1.TabIndex = 0
            ' dataGrid2
            Me.dataGrid2.AllowDrop = True
            Me.dataGrid2.DataMember = ""
            Me.dataGrid2.HeaderForeColor = System.Drawing.SystemColors.ControlText
            Me.dataGrid2.Location = New System.Drawing.Point(304, 24)
            Me.dataGrid2.Name = "dataGrid2"
            Me.dataGrid2.PreferredColumnWidth = 50
            Me.dataGrid2.Size = New System.Drawing.Size(224, 184)
            Me.dataGrid2.TabIndex = 1
            ' Form1
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(584, 253)
            Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.dataGrid2, Me.dataGrid1})
            Me.Name = "Form1"
            Me.Text = "Form1"
            AddHandler Me.Load, New System.EventHandler(AddressOf Form1_Load)
        CType(Me.dataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.dataGrid2, System.ComponentModel.ISupportInitialize).EndInit()

        End Sub
        <STAThread()> _
        Public Shared Sub Main()

            Application.Run(New Form1())

        End Sub
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)

        End Sub
        Public Class DnDDataGrid
            Inherits DataGrid
            Private dndMouseDownRow As Integer
            Private dndMouseDownCol As Integer
            Public Sub New()
                AddHandler Me.DragOver, New System.Windows.Forms.DragEventHandler(AddressOf HandleDragOver)
                AddHandler Me.DragDrop, New System.Windows.Forms.DragEventHandler(AddressOf HandleDragDrop)
                AddHandler Me.DragEnter, New System.Windows.Forms.DragEventHandler(AddressOf HandleDragEnter)
                AddHandler Me.MouseDown, New System.Windows.Forms.MouseEventHandler(AddressOf HandleMouseDown)
                AddHandler Me.MouseMove, New System.Windows.Forms.MouseEventHandler(AddressOf HandleMouseMove)
                AddHandler Me.MouseUp, New System.Windows.Forms.MouseEventHandler(AddressOf HandleMouseUp)
                Me.dndMouseDownRow = -(1)
                Me.dndMouseDownCol = -(1)
                Me.AllowDrop = True

            End Sub
            Private Sub HandleMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)

                Me.dndMouseDownRow = -(1)
                Me.dndMouseDownCol = -(1)

            End Sub
            Private Sub HandleMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)

                Dim ht As System.Windows.Forms.DataGrid.HitTestInfo
                ht = Me.HitTest(New Point(e.X, e.Y))
                Me.dndMouseDownRow = ht.Row
                Me.dndMouseDownCol = ht.Column

            End Sub
            Private Sub HandleMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)

                Dim ht As System.Windows.Forms.DataGrid.HitTestInfo
                ht = Me.HitTest(New Point(e.X, e.Y))
                If (e.Button = MouseButtons.Left) Then
                    'Console.WriteLine(ht.ToString() );
                    If (((dndMouseDownRow = -(1)) _
                                OrElse (dndMouseDownCol = -(1))) _
                                OrElse ((ht.Row = dndMouseDownRow) _
                                AndAlso (ht.Column = dndMouseDownCol))) Then
                    End If
                    Dim data As [String]
                    data = Me(Me.dndMouseDownRow, Me.dndMouseDownCol).ToString
                    'Console.WriteLine(ht.ToString() + "\n" + data);
                    Me.DoDragDrop(data, DragDropEffects.Copy)
                    Me.dndMouseDownRow = -(1)
                    Me.dndMouseDownCol = -(1)
                End If

            End Sub
            Private Sub HandleDragOver(ByVal sender As Object, ByVal e As DragEventArgs)

                Dim ht As System.Windows.Forms.DataGrid.HitTestInfo
                ht = Me.HitTest(Me.PointToClient(New Point(e.X, e.Y)))
                If (((ht.Row = Me.dndMouseDownRow) _
                            AndAlso (ht.Column = Me.dndMouseDownCol)) _
                            OrElse Not (e.Data.GetDataPresent("Text"))) Then
                    e.Effect = DragDropEffects.None
                    e.Effect = DragDropEffects.Copy
                End If

            End Sub
            Private Sub HandleDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)

                If e.Data.GetDataPresent("Text") Then
                    e.Effect = DragDropEffects.Copy
                End If

            End Sub
            Private Sub HandleDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)

                'DataGrid dg = sender as DataGrid;
                'if(dg == null) return;
                If e.Data.GetDataPresent("Text") Then
                    Dim ht As System.Windows.Forms.DataGrid.HitTestInfo
                    ht = Me.HitTest(Me.PointToClient(New Point(e.X, e.Y)))
                    If ((ht.Row = -(1)) _
                                OrElse (ht.Column = -(1))) Then
                        Me(ht.Row, ht.Column) = CType(e.Data.GetData("Text"), String)
                    End If
                End If

            End Sub
        End Class
    End Class


Author Comment

ID: 13679329

Thanks for your reply.  Although it didnt directly solve my problem it made me realise what i had done wrong.

My mistake was in the line: hti2 = myGrid.HitTest(PointToClient(pt))

It should have been: hti2 = myGrid.HitTest(*myGrid*.PointToClient(pt))

I will give you the points because i probably wouldnt have realised unless i saw the line in your reply that says:

 ht = Me.HitTest(Me.PointToClient(New Point(e.X, e.Y)))

Its when i say the Me. infront of the pointToClient that i realised my mistake.

Thanks for your help :)

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Loops Section Overview
Suggested Courses

579 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question