ComponentOne True DBGrid for WinForms
Tutorial 13: Implementing Drag-and-Drop Functionality
True DBGrid for WinForms Tutorials > Tutorial 13: Implementing Drag-and-Drop Functionality

In this tutorial, you will learn how to implement drag-and-drop functionality in True DBGrid for WinForms.

Set up the True DBGrid for WinForms controls

Complete the following steps:

  1. Start a new .NET project
  2. Place two C1TrueDBGrid controls (C1TrueDBGrid1, C1TrueDBGrid2) onto the form. Also add three labels onto the form and arrange them to look like the picture below.
  3. In the C1TrueDBGrid Tasks menu for C1TrueDBGrid1, locate the Choose Data Source drop-down and select Add Project Data Source. In the adapter's Data Source Configuration Wizard, either select a connection to C1NWind.mdb or create a new connection to this database. On the Choose your database objects page of the wizard, select all fields in the Customers table and type "DsCustomers" into the DataSet name box, and then finish out the wizard.
  4. In the C1TrueDBGrid Tasks menu for C1TrueDBGrid2, locate the Choose Data Source drop-down and select Add Project Data Source. In the adapter's Data Source Configuration Wizard, either select a connection to C1NWind.mdb or create a new connection to this database. On the Choose your database objects page of the wizard, select all fields in the CallList table and type "DsCallList" into the DataSet name box, and then finish out the wizard.
  5. In the general section of the form, add the following declarations:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Dim _ptStartDrag As Point
    Dim _dragRow As Long
    

    To write code in C#

    C#
    Copy Code
    Point _ptStartDrag;
    long _dragRow;
    
  6. Visual Studio adds the following code to the Load event of Form1 to fill the new datasets:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Me.CallListTableAdapter.Fill(Me.DsCallList.CallList)
    Me.CustomersTableAdapter.Fill(Me.DsCustomers.Customers)
    

    To write code in C#

    C#
    Copy Code
    this.CallListTableAdapter.Fill(this.DsCallList.CallList);
    this.CustomersTableAdapter.Fill(this.DsCustomers.Customers);
    
  7. For the first grid (C1TrueDBGrid1) set the AllowDrag property to True. While, for the second grid, set the AllowDrop property to True.
  8. Right-click C1TrueDBGrid1 and select Retrieve Fields. Do the same with the other grid.
  9. Open up the C1TrueDBGrid Designer for C1TrueDBGrid1 by clicking on the ellipsis button next to the Columns property for the C1TrueDBGrid in the Properties window.
  10. Remove all of the columns from the grid except LastName, FirstName, Company, and Phone by clicking the Remove Column button for each column to remove. Enter the C1TrueDBGrid Designer for the other grid and remove all of its columns except Customer, Phone, and CallDate.
  11. In the Properties window set the MarqueeStyle for C1TrueDBGrid1 to SolidCellBorder. In the C1TrueDBGrid Designer set Column 3's (Phone) NumberFormat property to "(###)###-####". Open up the C1TrueDBGrid Designer for the second grid and set its Column 2's NumberFormat property to "(###)###-####". The grid should now look like the following:

Add code to your project

This section describes the code needed to drag the contents of a cell or row from C1TrueDBGrid1 to C1TrueDBGrid2. The code assumes that if you want to drag the entire row of data to C1TrueDBGrid2 in order to add a new record there.

  1. Add the following subroutine to the project to reset the MarqueeStyle property of each grid, which is used to provide visual feedback while dragging is in progress. The reset routine will be called to perform clean-up after a drag-and-drop operation concludes.

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub ResetDragDrop()
        ' Turn off drag-and-drop by resetting the highlight and label text.
        Me._ptStartDrag = Point.Empty
        Me._dragRow = - 1
        Me.C1TrueDBGrid1.MarqueeStyle = C1.Win.C1TrueDBGrid.MarqueeEnum.SolidCellBorder
        Me.C1TrueDBGrid2.MarqueeStyle = C1.Win.C1TrueDBGrid.MarqueeEnum.SolidCellBorder
        Me.Label3.Text = "Drag a row from the top grid and drop it on the bottom grid."
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void ResetDragDrop() 
    {
        // Turn off drag-and-drop by resetting the highlight and label text.
        this._ptStartDrag = Point.Empty;
        this._dragRow = - 1;
        this.c1TrueDBGrid1.MarqueeStyle = C1.Win.C1TrueDBGrid.MarqueeEnum.SolidCellBorder;
        this.c1TrueDBGrid2.MarqueeStyle = C1.Win.C1TrueDBGrid.MarqueeEnum.SolidCellBorder;
        this.label3.Text = "Drag a row from the top grid and drop it on the bottom grid.";
    }
    
  2. Enter the following code to handle the mouse related events:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub C1TrueDBGrid1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles C1TrueDBGrid1.MouseDown
        Dim row, col As Integer
        Me._ptStartDrag = Point.Empty
        Me._dragRow = - 1
        If Me.C1TrueDBGrid1.CellContaining(e.X, e.Y, row, col) Then
     
            ' Save the starting point of the drag operation.
            Me._ptStartDrag = New Point(e.X, e.Y)
            Me._dragRow = row
        End If
    End Sub
     
    Private Sub C1TrueDBGrid1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles C1TrueDBGrid1.MouseMove
     
        ' If we don't have an empty start drag point, then the drag has been initiated.
        If Not Me._ptStartDrag.IsEmpty Then
     
            ' Create a rectangle that bounds the start of the drag operation by 2 pixels.
            Dim r As New Rectangle(Me._ptStartDrag, Size.Empty)
            r.Inflate(2, 2)
     
            ' If we've moved more than 2 pixels, start the drag operation.
            If Not r.Contains(e.X, e.Y) Then
                Me.C1TrueDBGrid1.Row = Me._dragRow
                Me.C1TrueDBGrid1.MarqueeStyle = C1.Win.C1TrueDBGrid.MarqueeEnum.HighlightRow
                Me.C1TrueDBGrid1.DoDragDrop(Me._dragRow, DragDropEffects.Copy)
            End If
        End If
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void C1TrueDBGrid1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
    {
        int row, col;
        this._ptStartDrag = Point.Empty;
        this._dragRow = - 1;
        if (this.c1TrueDBGrid1.CellContaining(e.X, e.Y, row, col) ) 
        {
            // Save the starting point of the drag operation.
            this._ptStartDrag = new Point(e.X, e.Y);
            this._dragRow = row;
        }
    }
     
    private void C1TrueDBGrid1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 
    {
        // If we don't have an empty start drag point, then the drag has been initiated.
        if (!this._ptStartDrag.IsEmpty ) 
        {
            // Create a rectangle that bounds the start of the drag operation by 2 pixels.
            Rectangle  r = new Rectangle(this._ptStartDrag, Size.Empty);
            r.Inflate(2, 2);
     
            // If we've moved more than 2 pixels, start the drag operation.
            if (!r.Contains(e.X, e.Y) ) 
            {
                this.c1TrueDBGrid1.Row = this._dragRow;
                this.c1TrueDBGrid1.MarqueeStyle = C1.Win.C1TrueDBGrid.MarqueeEnum.HighlightRow;
                this.c1TrueDBGrid1.DoDragDrop(this._dragRow, DragDropEffects.Copy);
            }
        }
    }
    
  3. Enter the following code to handle the dragging and dropping events:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub C1TrueDBGrid2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles C1TrueDBGrid2.DragEnter
        Me.Label3.Text = "Create a new record when dropped..."
        e.Effect = DragDropEffects.Copy
    End Sub
     
    Private Sub C1TrueDBGrid2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles C1TrueDBGrid2.DragDrop
        Try
            Dim row As Integer = CInt(e.Data.GetData(GetType(Integer)))
     
            ' Use the grid's indexer to get some data.
            Dim custname As String = Me.C1TrueDBGrid1(row, "FirstName").ToString()
     
            ' Use the CellText() method to get some data.
            custname += " " + Me.C1TrueDBGrid1.Columns("LastName").CellText(row)
     
            ' Use the CellValue() method to get some data.
            custname += " " + Me.C1TrueDBGrid1.Columns("Company").CellValue(row).ToString()
     
            ' Add a new row to the data set for the bottom grid.
            Dim drv As DataRowView = Me.DsCallList.CallList.DefaultView.AddNew()
            drv("CallDate") = DateTime.Now
            drv("Customer") = custname
            drv("Phone") = Me.C1TrueDBGrid1.Columns("Phone").Value.ToString()
            drv.EndEdit()
            Me.C1TrueDBGrid2.MoveLast()
            Me.C1TrueDBGrid2.Select()
     
            ' Commit changes to the database.
            Dim inserted As DataSet = Me.DsCallList.GetChanges(DataRowState.Added)
            If Not (inserted Is Nothing) Then
                Me.CallListTableAdapter.Update(inserted)
            End If
            Me.ResetDragDrop()
    
        Catch ex As System.Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void C1TrueDBGrid2_DragEnter(object sender,  System.Windows.Forms.DragEventArgs e) 
    {
        this.label3.Text = "Create a new record when dropped...";
        e.Effect = DragDropEffects.Copy;
    }
     
    private void C1TrueDBGrid2_DragDrop(object sender,  System.Windows.Forms.DragEventArgs e) 
    {
        try 
        {
            int row = (int)e.Data.GetData(typeof(int));
     
            // Use the grid's indexer to get some data.
            string  custname = this.c1TrueDBGrid1[row, "FirstName"].ToString();
     
            // Use the CellText() method to get some data.
            custname += " " + this.c1TrueDBGrid1.Columns["LastName"].CellText(row);
     
            // Use the CellValue() method to get some data.
            custname += " " + this.c1TrueDBGrid1.Columns["Company"].CellValue(row).ToString();
     
            // Add a new row to the data set for the bottom grid.
            DataRowView drv = this.DsCallList.CallList.DefaultView.AddNew();
            drv["CallDate"] = DateTime.Now;
            drv["Customer"] = custname;
            drv["Phone"] = this.c1TrueDBGrid1.Columns["Phone"].Value.ToString();
            drv.EndEdit();
            this.c1TrueDBGrid2.MoveLast();
            this.c1TrueDBGrid2.Select();
     
            // Commit changes to the database.
            DataSet inserted = this.DsCallList.GetChanges(DataRowState.Added);
            if (! (inserted == null) ) 
            {
                this.CallListTableAdapter.Update(inserted);
            }
             this.ResetDragDrop();
    
        } 
        catch (System.Exception ex) 
        { 
            MessageBox.Show(ex.Message);
        }
    }
    

Run the program and observe the following:

You've successfully completed implementing drag-and-drop in C1TrueDBGrid; this concludes tutorial 13.