JohnLM 14 Posted December 27, 2022 (edited) Win7, D11.2, FMX app, using TStringGrid and FireDAC and SQLite I was wondering, is it possible to make the TStringGrid have a drag or moveable rows feature? In a barcode app that I am working on, there will be times when I might want to reorient some of the rows that I scan barcodes off of products. I have a [delete] tbutton feature to delete rows. When I do this, I will resync the line numbers only. So, say I delete some rows and/or want to move one or more rows, the line number order will be out of sync. Sorting them shouldn't be a problem for just that column, while the remaining columns will stay in the same order. I can re-sort just the [Line Number] column. Back to the drag/move rows.. Methods: 1) Because my S10+ phone is so small, I use a pen for it most of the time. That is what I will use to move the rows up/down. So, I'd like to be able to drag rows that way. But if it is not possible, then 2) be able to move rows up/down using two tbuttons for the [up] and [down] on the form instead. What do you guys think? Is there a way to make this happen for the TStringGrid component? Edited December 27, 2022 by JohnLM Share this post Link to post
programmerdelphi2k 237 Posted December 27, 2022 (edited) hi @JohnLM first, in FMX StringGrid/Grid all values is a "string" by default! each column is independent each other there is not "row concept", but "Cols with lines"... Then, you has many "lines" in a column! you can try using "mouse event" or drag'n'drop! here my sample using "mouse event": Here, I'm not testing if the values are OK, or if it's the same line, etc... just showing a general idea of the process! The rest is up to you! // FMX StringGrid using mouse event to "move" content of each "row" in all columns type TMyCellsData = TArray<string>; TRecRowContent = record FRow: integer; // what is the row? FData: TMyCellsData; // what is the data? = all in string representation end; var LRowSrcContent: TRecRowContent; LRowTrgContent: TRecRowContent; LRowMoving : boolean = false; procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.OnMouseDown := MyOnMouseDown; StringGrid1.OnMouseUp := MyOnMouseUp; // StringGrid1.Options := StringGrid1.Options + [TGridOption.RowSelect]; // avoid "edit cell" on click! end; // simulating a rowwwwwwwwwwwwwwwwwwww....... in col1 + col2 + col3 + ... procedure MyGetWholeRow(AStringGrid: TStringGrid; ARow: integer; out AMyCellsData: TRecRowContent); begin AMyCellsData.FRow := ARow; // what is the row? AMyCellsData.FData := []; // clear old-datas // for var i: integer := 0 to (AStringGrid.ColumnCount - 1) do AMyCellsData.FData := AMyCellsData.FData + [AStringGrid.Cells[i, ARow]]; end; procedure TForm1.MyOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin inherited; // if (ssCtrl in Shift) then // using "Ctrl" just for test begin MyGetWholeRow(StringGrid1, StringGrid1.RowByPoint(X, Y), LRowSrcContent); // LRowMoving := true; end; end; procedure TForm1.MyOnMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); var LRow: integer; begin inherited; // if LRowMoving and (ssCtrl in Shift) then begin LRow := StringGrid1.RowByPoint(X, Y); // MyGetWholeRow(StringGrid1, LRow, LRowTrgContent); // before override row-datas // for var i: integer := 0 to high(LRowSrcContent.FData) do // move data StringGrid1.Cells[i, LRowTrgContent.FRow] := LRowSrcContent.FData[i]; // for var i: integer := 0 to high(LRowTrgContent.FData) do // restore row-datas StringGrid1.Cells[i, LRowSrcContent.FRow] := LRowTrgContent.FData[i]; end; // LRowMoving := false; LRowSrcContent.FRow := -1; LRowSrcContent.FData := []; LRowTrgContent.FRow := -1; LRowTrgContent.FData := []; end; Edited December 27, 2022 by programmerdelphi2k Share this post Link to post
JohnLM 14 Posted December 29, 2022 I will have a look at this later. I'm trying to work out another unrelated issue that came up in and can't seem to get it working. As always, thanks for your response. Share this post Link to post