Example 28 : Using row, cell, cell ranges and column drag & dropStarting from v1.91, extensive support for automatic drag & drop is included in TAdvStringGrid. With this example application, the power of this is shown. Because drag & drop conforms to OLE based drag & drop, this makes drag & drop possible not only within your application but also between applications that conform to this standard such as Excel, Word or even other applications with TAdvStringGrid.
Making use of these capabilities is done through several properties and events:
OleDropSource: make the grid act as a source for drag & drop
OleDropTarget : make the grid act as a target for drag & drop
OleEntireRows : make sure that entire row (including fixed row) is handled during drag & drop in RowSelect mode
OleInsertRows : perform automatic row insertion when rows are dropped on the grid
OleRemoveRows : perform automatic row removal if drag & drop move operation is done, otherwise the move will result in empty rows
Some other properties that might be overlooked but nevertheless play an important role in drag & drop are : In Navigation:
Navigation.AllowClipboardAlways : will allow drop on a grid where editing is disabled. Otherwise, only editable cells could change through the drop operation.
Navigation.AllowClipboardRowGrow : will allow automatic adding of rows if more rows are dropped on the grid than present
Navigation.AllowClipboardColGrow : will allow automatic adding of columns if more columns are dropped on the grid than present
ExcelClipboardFormat:boolean : use clipboard format compatible with Excel
OnOleDrag : event triggered when drag starts. Through the Allow parameter, the drag can be enabled or not.
OnOleDragOver : event triggered during the drag operation when the mouse is over the grid. Through the Allow parameter, the place where data can be dropped can be set.
OnOleDragStart : event triggered when drag has started.
OnOleDragStop : event triggered when drag has stopped. Indicates whether it was a move, copy or cancelled drag & drop operation.
OnOleDrop : event triggered when succesfull drop of cells was performed on the grid.
OnOleDropCol : event triggered when succesfull drop of a column was performed on the grid.
Row drag & drop
Enabling row drag and drop is simple. OleDropSource and OleDropTarget properties are set true. In addition OleEntireRows, OleRemoveRows and OleInsertRows are set true to enable full row drag & drop. The only event used further is OnOleDrag where Allow is set true whenever the origin row of the drag operation is not a fixed row. This is necessary, as drag & drop from a fixed row starts a column drag & drop. Notice that drag & drop between grids as well as in the grid itself (to allow row rearranging is possible)
To allow only drag & drop between grids, use the OnOleDragStart event to set the source grid in a variable. In the OnOleDragOver event, set Allow to false if the Sender is equal to this source. Finally reset the source on the OnOleDragStop event.
ddsource:TObject; procedure Form1.OnOleDragStart(Sender:TObject; Arow,Acol: integer); begin ddsource := Sender; end; procedure Form1.OnOleDragOver(Sender:TObject; Arow,Acol: integer; var Allow: boolean); begin Allow := ddsource <> Sender; end; procedure Form1.OnOleDragStop(Sender:TObject; Arow,Acol: integer; var Allow: boolean); begin ddsource := nil; end;
Cell drag & drop
Everything under row drag & drop applies to cell drag & drop, except that OleEntireRows, OleRemoveRows and OleInsertRows are set false here.
Column drag & drop
Column drag & drop is a little more involved. This is because the interface allows for more than just inter grid column drag & drop but allows the implementation for something like a field chooser (see example project 29 ) as well.
Where the previous examples disabled column drag & drop by setting Allow=false when the drag started from the fixed row, this example only enables drag & drop when the drag starts from the fixed row. (Nothing prevents enabling both in the same grid though)
The OnOleDragOver event is used to allow a drop of a column only when the mouse cursor is over a fixed row. Except when the grid has no columns, a drop on the fixed column is not allowed:
procedure TForm1.OnOleDragOver(Sender: TObject; Arow, Acol: integer; var Allow: boolean); begin with Sender as TAdvStringGrid do Allow := (Sender<>ColSource) and (Arow=0) and ((Acol>0) or (ColCount=1)); end;
The event OnOleDropCol is triggered when a column is dropped. It indicates the index of the original column dropped as well as the index of the column where it is dropped. It is in this event that the column data of the source grid is inserted in the target grid:
procedure TForm1.AdvStringGrid5OleDropCol(Sender: TObject; Arow, Acol, DropCol: Integer); var sl:TStringList; begin coltarget := Sender as TAdvStringGrid; sl := TStringList.Create; sl.Assign(colsource.Cols[DropCol]); if (acol=0) then inc(acol); coltarget.InsertCols(acol,1); coltarget.Cols[acol].Assign(sl); sl.Free; end;
Finally the OnOleDragStop event is used to remove the column from the source grid if the drag & drop was a move operation:
procedure TForm1.AdvStringGrid5OleDragStop(Sender: TObject; OLEEffect: Integer); begin if OLEEffect=DROPEFFECT_MOVE then begin colsource.RemoveCols(colsourceidx,1); end; end;
With this little additional coding, full drag & drop of columns between grids was achieved.
Delphi project & source files for downloading included in the main demos distribution for Delphi.