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