I want to put a checkbox on a single cell (not a checkcolunn) of a FMX stringgrid.
I think that I need to use 'StringGrid1.AddObject' but I do not know how to go from there.
CodePudding user response:
I don't understand you can't (but you change my code). First I want to say I am not a Stringgrid fan on Android but that's another point. Second point I focused on drawing, I also wrote some code to manage some others style containing a Tpath instead of a TStyleObject
procedure TForm1.StringGrid1DrawColumnCell(Sender: TObject;
const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF;
const Row: Integer; const Value: TValue; const State: TGridDrawStates);
var sb : TFMXObject;
aRectF : TRectF;
img : tfmxobject;
begin
if Assigned(Stylebook) then sb:=Stylebook.Style else sb:=TStyleManager.ActiveStyle(Self);
if Test.find(Column.Index,Row)>=0 then
begin
if Test[Test.Find(Column.Index,Row)].ischecked
then img := sb.FindStyleResource('checkcellstyle.checkboxchecked')
else img := sb.FindStyleResource('checkcellstyle.checkboxunchecked');
if assigned(img) then
begin
aRectf:=Bounds;
arectf.Left:=arectf.Right-20; // to adapt
TStyleObject(img).DrawToCanvas(Canvas,arectf,1);
end
else begin
img:= sb.FindStyleResource('checkcellstyle');
if assigned(img) then img:=img.FindStyleResource('checkmark');
if assigned(img) and (img is Tpath) then
begin
if Test[Test.Find(Column.Index,Row)].ischecked
then Tpath(img).Fill.Color:=TColorAnimation(Img.Children[0]).StopValue
else Tpath(img).Fill.Color:=TColorAnimation(Img.Children[0]).StartValue;
var bmp:=Tpath(Img).MakeScreenshot;
aRectf:=Bounds;
arectf.Left:=arectf.Right-20; // to adapt
Canvas.DrawBitmap(bmp,Trectf.Create(0,0,bmp.Width,bmp.Height),aRectf,1);
end;
end;
end;
end;
but this is not a problem here.
Here is two screenshots, proving my code works. First one I use transparent.style wich as a default platform
then I add C:\Users\Public\Documents\Embarcadero\Studio\22.0\Styles\Android\AndroidWearDarkBlue.fsf and got this one
What is still not clear for me on Android is the way to check/oncheck value on Android. Sometimes CellDblclick event works, sometimes not !
CodePudding user response:
You can't, because Cells[col,raw] is a string, and there is no cell selection support. But if you manage a List of selected cells somewhere and use OnDrawCellEvent, it's possible.
Here is a "dirty" sample, but you can see I use Style:
And how I manage this:
procedure TForm1.FormCreate(Sender: TObject);
begin
SelectedCells:=TList<String>.Create(['0,2']);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
SelectedCells.Free;
end;
procedure TForm1.StringGrid1CellDblClick(const Column: TColumn;
const Row: Integer);
begin
if SelectedCells.IndexOf(Format('%d,%d',[Column.Index,Row]))>=0
then SelectedCells.Remove(Format('%d,%d',[Column.Index,Row]))
else SelectedCells.Add(Format('%d,%d',[Column.Index,Row]));
end;
procedure TForm1.StringGrid1DrawColumnCell(Sender: TObject;
const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF;
const Row: Integer; const Value: TValue; const State: TGridDrawStates);
var sb : TFMXObject;
aRectF : TRectF;
begin
if Assigned(Stylebook) then sb:=Stylebook.Style else sb:=TStyleManager.ActiveStyle(Self);
if SelectedCells.IndexOf(Format('%d,%d',[Column.Index,Row]))>=0 then
begin
var img := sb.FindStyleResource('checkcellstyle.checkboxchecked');
if assigned(img) then
begin
aRectf:=Bounds;
arectf.Left:=arectf.Right-20; // to adapt
TStyleObject(img).DrawToCanvas(Canvas,arectf,1);
end;
end;
end;
Caveats: not all styles can be used, I think.
CodePudding user response:
I reworked the answer of SergeGirard
unit Main;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Rtti,
FMX.Grid.Style, FMX.Grid, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Edit,
System.Generics.Collections, FMX.Styles, FMX.Styles.Objects, FMX.StdCtrls,
FMX.Objects;
Const
CHECKBOX_COLUMN = 0;
CHECKBOX_ROW = 2;
SYSTEM_ON = $101;
SYSTEM_OFF = $100;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
CurrencyColumn1: TCurrencyColumn;
StyleBook1: TStyleBook;
procedure FormCreate(Sender: TObject);
procedure StringGrid1DrawColumnCell(Sender: TObject; const Canvas: TCanvas;
const Column: TColumn; const Bounds: TRectF; const Row: Integer;
const Value: TValue; const State: TGridDrawStates);
procedure Grid1GetValue(Sender: TObject; const ACol, ARow: Integer;
var Value: TValue);
procedure FormDestroy(Sender: TObject);
procedure StringGrid1CellClick(const Column: TColumn; const Row: Integer);
procedure StringGrid1SelectCell(Sender: TObject; const ACol, ARow: Integer;
var CanSelect: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
SelectedCells: TList<string>;
implementation
{$R *.fmx}
{$R *.LgXhdpiTb.fmx ANDROID}
{$R *.LgXhdpiPh.fmx ANDROID}
{$R *.Windows.fmx MSWINDOWS}
{$R *.NmXhdpiPh.fmx ANDROID}
{$R *.SmXhdpiPh.fmx ANDROID}
procedure TForm1.FormCreate(Sender: TObject);
Var
iRow: Integer;
MyStyle: TFmxObject;
begin
for iRow := 0 to 10 do
StringGrid1.Cells[0, iRow] := iRow.ToString;
StringGrid1.Cells[CHECKBOX_COLUMN, CHECKBOX_ROW] := SYSTEM_OFF.ToString;
SelectedCells := TList<String>.Create
([CHECKBOX_COLUMN.ToString ',' CHECKBOX_ROW.ToString]);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
SelectedCells.Free;
end;
procedure TForm1.Grid1GetValue(Sender: TObject; const ACol, ARow: Integer;
var Value: TValue);
Var
i: Integer;
begin
//Fill column with some numbers
for i := 1 to 10 do
if (ACol = 0) AND (ARow = i - 1) then
Value := i;
end;
procedure TForm1.StringGrid1CellClick(const Column: TColumn;
const Row: Integer);
begin
if (Column.Index = CHECKBOX_COLUMN) AND (Row = CHECKBOX_ROW) then
Begin
If StringGrid1.Cells[CHECKBOX_COLUMN, CHECKBOX_ROW] =
SYSTEM_OFF.ToString
then
StringGrid1.Cells[CHECKBOX_COLUMN, CHECKBOX_ROW] :=
SYSTEM_ON.ToString
else
StringGrid1.Cells[CHECKBOX_COLUMN, CHECKBOX_ROW] :=
SYSTEM_OFF.ToString;
End;
StringGrid1.Repaint;
end;
procedure TForm1.StringGrid1DrawColumnCell(Sender: TObject;
const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF;
const Row: Integer; const Value: TValue; const State: TGridDrawStates);
var
sb: TFmxObject;
aRectF: TRectF;
img: TFmxObject;
begin
if Assigned(Stylebook) then
sb := Stylebook.Style
else
sb := TStyleManager.ActiveStyle(Self);
if SelectedCells.IndexOf(Format('%d,%d', [Column.Index, Row])) >= 0 then
begin
if StringGrid1.Cells[CHECKBOX_COLUMN, CHECKBOX_ROW].ToInteger = SYSTEM_ON
then
Begin
img := sb.FindStyleResource('checkcellstyle.checkboxchecked');
End
else
Begin
img := sb.FindStyleResource('checkcellstyle.checkboxunchecked');
End;
if Assigned(img) then
begin
aRectF := Bounds;
aRectF.Left := aRectF.Right - 90; // to adapt
TStyleObject(img).DrawToCanvas(Canvas, aRectF, 1);
StringGrid1.Repaint;
end;
end;
end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject;
const ACol, ARow: Integer; var CanSelect: Boolean);
begin
if (ACol = CHECKBOX_COLUMN) AND (ARow = CHECKBOX_ROW) then
CanSelect := False
else
CanSelect := true;
end;
end.`
As the pictures show this works perfectly on windows 32. However not on Android. Indeed it has something to do with the style (checkcellstyle.checkboxchecked is never found). I can not find a working style for Android any suggestions?