delphi - Add a TCombobox Column to a Firemonkey TGrid -
this question appears have been answered already, possibly monkeystyler/mike sutton, however, using delphi 10 seattle, provided code , guides don't work anymore.
doesn't work because applystyling event handler called once (at column create)
i want add tcombobox or tcomboboxedit column atgrid.
type tcombocolumn = class(tcolumn) protected function createcellcontrol: tstyledcontrol; override; // works! end;
...
grid1.addobject(tcombocolumn.create(grid1));
...
function tcombocolumn.createcellcontrol: tstyledcontrol; begin result := tcombobox.create(self); tcombobox(result).items.add('a'); tcombobox(result).items.add('b'); tcombobox(result).items.add('c'); tcombobox(result).onchange := dotextchanged; // strange hooks end;
this creates combobox column in grid, it's same combobox in every row, , have no idea how add getvalue , setvalue methods applicable here.
you need quite much. let's start. @ first need declare data type store values combobox
column.
tcomborecord = record fieldvalues: array of string; itemselected: integer; function selected: string; end; ... { tcomborecord } function tcomborecord.selected: string; begin result := fieldvalues[itemselected]; end;
and populate tlist<tcomborecord>
data.
var combodata: tlist<tcomborecord>; procedure populatecombodata(rows: cardinal); implementation procedure populatecombodata(rows: cardinal); var rowi: cardinal; i: cardinal; comr: tcomborecord; begin rowi := 1 rows begin setlength(comr.fieldvalues, random(5) + 1); := 0 length(comr.fieldvalues) - 1 comr.fieldvalues[i] := inttostr(random(64000)); comr.itemselected := 0; combodata.add(comr); end; end; initialization combodata := tlist<tcomborecord>.create; finalization combodata.free;
than need create tcombobox
ascendant store , manipulate tcomborecord
type data.
tcomboboxcell = class(tcombobox) private fcombodata: tcomborecord; procedure setcombodata(const value: tcomborecord); function getcombodata: tcomborecord; protected procedure setdata(const value: tvalue); override; public property combodata: tcomborecord read getcombodata write setcombodata; end; ... { tcomboboxcell } function tcomboboxcell.getcombodata: tcomborecord; begin fcombodata.itemselected:=itemindex; result:=fcombodata; end; procedure tcomboboxcell.setcombodata(const value: tcomborecord); var s: string; begin fcombodata := value; items.clear; s in value.fieldvalues items.add(s); itemindex := value.itemselected; end; procedure tcomboboxcell.setdata(const value: tvalue); begin inherited; combodata := value.astype<tcomborecord> end;
than need inherit new class form tcolumn
:
tcombocolumn = class(tcolumn) protected procedure docombochanged(sender: tobject); function grid: tcomboextendedgrid; overload; function createcellcontrol: tstyledcontrol; override; end; ... { tcombocolumn } function tcombocolumn.createcellcontrol: tstyledcontrol; begin result := tcomboboxcell.create(self); tcomboboxcell(result).onchange := docombochanged; end; procedure tcombocolumn.docombochanged(sender: tobject); var p: tpointf; lgrid: tcomboextendedgrid; begin lgrid := grid; if not assigned(lgrid) exit; if fupdatecolumn exit; if fdisablechange exit; p := stringtopoint(tfmxobject(sender).tagstring); lgrid.setvalue(trunc(p.x), trunc(p.y), tvalue.from<tcomborecord>(tcomboboxcell(sender).combodata)); if assigned(lgrid.foneditingdone) lgrid.foneditingdone(grid, trunc(p.x), trunc(p.y)); end; function tcombocolumn.grid: tcomboextendedgrid; var p: tfmxobject; begin result := nil; p := parent; while assigned(p) begin if p tcustomgrid begin result := tcomboextendedgrid(p); exit; end; p := p.parent; end; end;
you see have subtype tgrid
class have handler grid
function , need access protected
foneditingdone
variable
tcomboextendedgrid = class(tgrid) private foneditingdone: toneditingdone; protected procedure setvalue(col, row: integer; const value: tvalue); override; end; { tcomboextendedgrid } procedure tcomboextendedgrid.setvalue(col, row: integer; const value: tvalue); begin inherited; end;
finally need set necessary creation , event handliing mechanism in our form unit. add column variable declaration.
protected cccolumn:tcombocolumn;
populate combodata , create column:
procedure tform1.button1click(sender: tobject); begin populatecombodata(grid2.rowcount); cccolumn:=tcombocolumn.create(grid2); cccolumn.parent := grid2; cccolumn.header := 'cb'; end;
and handle events:
procedure tform1.grid2getvalue(sender: tobject; const col, row: integer; var value: tvalue); begin case col of 6{combo column number}: value:=tvalue.from<tcomborecord>(combodata[row]) end; end; procedure tform1.grid2setvalue(sender: tobject; const col, row: integer; const value: tvalue); begin case col of 6{combo column number}: showmessage(value.astype<tcomborecord>.selected); end; end;
do not forget pass changes (if need) combodata
list. current handlers not you. prefer making in grid2setvalue
event handler.
Comments
Post a Comment