ComponentOne True DBGrid for WinForms
True DBGrid for WinForms Tutorials / Tutorial 13: Implementing Drag-and-Drop Functionality
In This Topic
    Tutorial 13: Implementing Drag-and-Drop Functionality
    In This Topic

    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.