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.

firemonkey grid basics

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

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -