Skip to main content

How to Enable Drag-and-Drop Operations between a Data Grid and a Scheduler

  • 2 minutes to read

The example shows how to provide a drag-and-drop functionality that will enable end-users to move a user event from a TDBGrid control to a scheduler.

Since this task requires a selected row to be identified with a mouse click, a data grid’s DragMode property must be set to dmManual and a grid’s OnMouseDown and OnMouseMove events must be handled to initiate a drag operation.

This example assumes that a data store (which is linked to a data grid) persists data in a format required by the scheduler’s storage (to learn more about the scheduler’s data structure, refer to the Bound Mode help topic). In the example, the store has been named EventsTable.

To copy data from a data grid to a scheduler in response to a drop action, handle a scheduler’s OnDragOver and OnDragDrop events. For demonstration purposes, a limited set of user event attributes (Caption, Duration and LabelColor) are transferred. In a real project, consider the implementation of a value object, which contains all the transient information.

// ...
type
  OldPoint: TPoint;
// ...
procedure TDemoBasicMainForm.DBGridMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  ARowIndex: Integer;
begin
  ARowIndex := 0;
  EventsTable.Bookmark := DBGrid.SelectedRows[ARowIndex];
  OldPoint := Point(X, Y);
end;
procedure TDemoBasicMainForm.DBGridMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  if (ssLeft in Shift) and ((Abs(OldPoint.X - X) > 2) or (Abs(OldPoint.Y - Y) > 2)) then
    TDBGrid(Sender).BeginDrag(True);
end;
procedure TDemoBasicMainForm.SchedulerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := Source = DBGrid;
end;
procedure TDemoBasicMainForm.SchedulerDragDrop(Sender, Source: TObject; X, Y: Integer);
var
  AStartDateTime, ADuration: TDateTime;
begin
  AStartDateTime := 0;
  with TcxScheduler(Sender) do
  begin
    if ActiveHitTest.HitAtTime then
      AStartDateTime := ActiveHitTest.Time;
  end;
  if AStartDateTime <> 0 then
  begin
    ADuration := EventsTable['Finish'] - EventsTable['Start'];
    EventsTable.Edit;
    EventsTable['Start'] := AStartDateTime;
    EventsTable['Finish'] := AStartDateTime + ADuration;
    EventsTable.Post;
  end;      
end;

The following image shows the result:

See Also