ComponentOne True DBGrid for .NET (2.0) Search HelpCentral 

Tutorial 13 – Implementing Drag-and-Drop in C1TrueDBGrid

In this tutorial, you will learn how to implement drag-and-drop functionality in C1TrueDBGrid. Begin by setting up the C1TrueDBGrid controls:

1.   Start a new .NET project

2.   Place two True DBGrid 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 TrueDBGrid 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 TDBGDemo.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 TrueDBGrid 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 TDBGDemo.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:

·      Visual Basic

Dim _ptStartDrag As Point

Dim _dragRow As Long

·      C#

Point _ptStartDrag;

long _dragRow;

·      Delphi

FDragRow: LongInt;

FptStartDrag: Point;

6.   Visual Studio adds the following code to the Load event of Form1 to fill the new datasets:

·      Visual Basic

Me.CallListTableAdapter.Fill(Me.DsCallList.CallList)

Me.CustomersTableAdapter.Fill(Me.DsCustomers.Customers)

·      C#

this.CallListTableAdapter.Fill(this.DsCallList.CallList);

this.CustomersTableAdapter.Fill(this.DsCustomers.Customers);

·      Delphi

Self.CallListTableAdapter.Fill(Self.DsCallList.CallList);

Self.CustomersTableAdapter.Fill(Self.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 on 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 True DBGrid in the Properties window.

10.  Remove all of the columns from the grid except LastName, FirstName, Company, and Phone by clicking the Delete selected columns button. 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:

Adding 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.

·      Visual Basic

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

·      C#

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.";

}

·      Delphi

procedure TWinForm.ResetDragDrop;

begin

  // Turn off drag-and-drop by resetting the highlight and label text.

  FptStartDrag := Point.Empty;

  FDragRow := -1;

  Self.C1TrueDBGrid1.MarqueeStyle := MarqueeEnum.SolidCellBorder;

  Self.C1TrueDBGrid2.MarqueeStyle := MarqueeEnum.SolidCellBorder;

  Self.label1.Text := 'Drag a row from the top grid and drop it on the bottom grid.';

end;

2.   Enter the following code to handle the mouse related events:

·      Visual Basic

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

·      C#

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);

        }

    }

}

·      Delphi

procedure TWinForm.C1TrueDBGrid1_MouseMove(sender: System.Object; e: System.Windows.Forms.MouseEventArgs);

var

  R: Rectangle;

begin

  // If we don't have an empty start drag point, then the drag has been initiated.

  if (not FPtStartDrag.IsEmpty) then

  begin

 

    // Create a rectangle that bounds the start of the drag operation by 2 pixels.

    R := Rectangle.Create(FptStartDrag,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

    begin

      Self.C1TrueDBGrid1.Row := FDragRow;

      Self.C1TrueDBGrid1.MarqueeStyle := MarqueeEnum.HighlightRow;

      Self.C1TrueDBGrid1.DoDragDrop(System.Object(FDragRow), DragDropEffects.Copy);

    end;

  end;

end;

 

procedure TWinForm.C1TrueDBGrid1_MouseDown(sender: System.Object; e: System.Windows.Forms.MouseEventArgs);

var

  Row, Col: Integer;

begin

  FPtStartDrag := Point.Empty;

  FDragRow := -1;

  if (Self.C1TrueDBGrid1.CellContaining(e.X, e.Y, row, col)) then

  begin

    // Save the starting point of the drag operation.

    FPtStartDrag := Point.Create(e.X, e.Y);

    FDragRow := row;

  end;

end;

3.   Enter the following code to handle the dragging and dropping events:

·      Visual Basic

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

    Catch ex As System.Exception

        MessageBox.Show(ex.Message)

    End Try

End Sub

·      C#

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);

        }

    }

    catch (System.Exception ex)

    {

        MessageBox.Show(ex.Message);

    }

}

·      Delphi

procedure TWinForm.C1TrueDBGrid2_DragEnter(sender: System.Object; e: System.Windows.Forms.DragEventArgs);

begin

  Label1.Text := 'Create a new record when dropped...';

  e.Effect := DragDropEffects.Copy;

end;

 

procedure TWinForm.C1TrueDBGrid2_DragDrop(sender: System.Object; e: System.Windows.Forms.DragEventArgs);

var Row: Integer;

  CustName: String;

  Drv: C1.Data.C1DataRow;

begin

  try

    Row := Integer(e.Data.GetData(typeof(Integer)));

 

    // Use the grid's indexer to get some data.

    CustName := c1TrueDBGrid1[Row,'FirstName'].ToString;

 

    // Use the CellText() method to get some data.

    CustName := CustName + ' ' + c1TrueDBGrid1.Columns['LastName'].CellText(Row);

 

    // Use the CellValue() method to get some data.

    CustName := CustName + ' ' + c1TrueDBGrid1.Columns['Company'].CellValue(Row).ToString;

 

    // Add a new row to the data set for the bottom grid.

    Drv := c1ExpressTable2.DataTable.AddNew;

    Drv['CallDate'] := DateTime.Now;

    Drv['Customer'] := CustName;

    Drv['Phone'] := c1TrueDBGrid1.Columns['Phone'].Value.ToString;

    Drv.EndEdit;

    Self.C1TrueDBGrid2.MoveLast;

    Self.C1TrueDBGrid2.Select;

 

    // Commit changes to the database.

    c1ExpressTable2.ExpressConnection.Update;

  except

    on Ex: System.Exception do MessageBox.Show(Ex.Message);

  end;

end;

Run the program and observe the following:

·      If an item in a column in C1TrueDBGrid1 is dragged, the entire row in C1TrueDBGrid1 is highlighted, indicating that the entire row of data is being dragged.

·      When dragging to TDBGrid2, the current cell marquee (a solid border around the cell) disappears.

·      If the data is dropped on C1TrueDBGrid2, a new record is created using the data from the current row of C1TrueDBGrid1.

This concludes the tutorial.


Send comments about this topic to ComponentOne.
Copyright © ComponentOne LLC. All rights reserved.