Firemonkey Grid Control - Align Column Right

I am using the FireMonkey grid control, but I have a problem trying to align the column. From the messages of other users, I managed to create a new type of TColumn, apply a style to it (text HorzAlign = taTrailing), and in theory I thought that it would be a solution. Values ​​are provided by the OnGetValue function for managing the grid.

The problem is that although at first it looks fine if you scroll the mouse wheel / mouse wheel, etc., a new column of type TColumn does not display correctly using the method / code below. This may be a bug / feature of the Grid (or the way I do it). I tried .ReAlign etc .; but to no avail. The only way to get the grid back to the row - for example, resize a column - which then redraws correctly?

The code below shows that it is a simple TGrid, with 2 columns, 1 standard StringColumn and 1 my new StringColNum (using the correct wuth alignment). - Any help is appreciated as this is a basic requirement for any grid work.

unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects, FMX.Grid, FMX.Layouts, FMX.Edit; type TForm1 = class(TForm) Grid1: TGrid; Button1: TButton; StyleBook1: TStyleBook; procedure Grid1GetValue(Sender: TObject; const Col, Row: Integer; var Value: Variant); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; TStringColNum = class(TStringColumn) private function CreateCellControl: TStyledControl; override; public constructor Create(AOwner: TComponent); override; published end; var Form1: TForm1; implementation {$R *.fmx} constructor TStringColNum.Create(AOwner: TComponent); begin inherited; end; function TStringColNum.CreateCellControl: TStyledControl; var t:TEdit; begin Result:=TStringColNum.Create(Self); Result.StyleLookup := 'textrightalign'; end; procedure TForm1.Button1Click(Sender: TObject); begin Grid1.AddObject(TStringColumn.Create(Self)); Grid1.AddObject(TStringColNum.Create(Self)); // Right Aligned column? Grid1.RowCount:=5000; Grid1.ShowScrollBars:=True; end; procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; var Value: Variant); var cell: TStyledControl; t: TText; begin if Col=0 then Value:='Row '+IntToStr(Row);; if Col=1 then begin cell := Grid1.Columns[Col].CellControlByRow(Row); if Assigned(cell) then begin t := (Cell.FindStyleResource('text') as TText); if Assigned(t) then t.Text:='Row '+IntToStr(Row); end; end; end; end. 

Sincerely. Yang.

+6
source share
5 answers

All this reminds me that I still have not written about this on the blog.

In any case, the grid cell can be any descendant of TStyledControl (basically any control). The default for a text cell is TTextCell, which is just TEdit. Being TEdit means changing alignment is very simple: just change the TextAlign property. No need to mess with styles (unless you really want to).

In your column, you need to create your cells in the CreateCellControl method. In fact, you are creating an instance of your column, which is your main problem.

You do not need the Create method for your column (it does nothing), so delete it (if you do not need something else) and make changes to CreateCellControl.

 function TStringColNum.CreateCellControl: TStyledControl; begin Result:=inherited; TTextCell(Result).TextAlign := taTrailing; end; 

Finally, your GetValue event handler should do nothing more than return a value:

 procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; var Value: Variant); begin if Col=0 then Value:='Row '+IntToStr(Row); if Col=1 then Value := 'Row '+IntToStr(Row); end; 
+5
source

Lowering columns do not work well with livebindings, since bindmanager creates columns, so you need to tinker with lowering this. In my opinion, neither an elegant, nor a practical approach.

Just align your cells in the OnPainting grid event.

 I := Col; for J := 0 to Grid1.RowCount - 1 do begin T := TTextCell(Grid1.Columns[I].Children[J]); T.TextAlign := TTextAlign.taTrailing; end; 
0
source

If you use livebindings, when you are less likely to customize the class of the column that is being created, but you can create helpers for the column that sets some attributes of the individual cell controls. Not too elegant, but simple and works:

 unit GridColumnHelper; interface uses Fmx.Types, Fmx.Controls, Fmx.Grid, Fmx.Edit; type TGridColumnHelper = class helper for TColumn public procedure SetEditMaxLength(aValue: Integer); procedure SetEditTextAlign(aValue: TTextAlign); end; implementation { TGridColumnHelper } procedure TGridColumnHelper.SetEditMaxLength(aValue: Integer); var lControl: TStyledControl; begin for lControl in FCellControls do begin if lControl is TEdit then (lControl as TEdit).MaxLength := aValue; end; end; procedure TGridColumnHelper.SetEditTextAlign(aValue: TTextAlign); var lControl: TStyledControl; begin for lControl in FCellControls do begin if lControl is TEdit then (lControl as TEdit).TextAlign := aValue; end; end; end. 

After the binding has filled the grid, you can call the helpers:

 MyGrid.Columns[0].SetEditTextAlign(TTextAlign.taTrailing); MyGrid.Columns[1].SetEditMaxLength(15); 
0
source

I think this is laziness Embarcadero.

adding / modifying 3 rows in FMX.Grid.pas solves this problem.

Instead of modifying the original FMX.Grid pas, I recommend copying the source FMX.Grid file to the Project directory, including in your project (add to the project) and add / modify the following lines.

 TColumn = class(TStyledControl) private const HorzTextMargin = 2; VertTextMargin = 1; private FReadOnly: Boolean; FHorizontalAlign:TTextAlign;//Add this Line ********* FEditMode: Integer; FApplyImmediately: boolean; ... ... procedure UpdateCell(ARow: Integer); published property HorizontalAlign: TTextAlign read FHorizontalAlign write FHorizontalAlign;//add this line ******* property Align; property ClipChildren default False; 

 procedure TColumn.DefaultDrawCell(const Canvas: TCanvas; const Bounds: TRectF; const Row: Integer; const Value: TValue; const State: TGridDrawStates); var R: TRectF; Layout: TTextLayout; LocalRow: Integer; begin if FDrawable <> nil then FDrawable.DrawCell(Canvas, Bounds, Row, Value, State) else ... ... Layout.Opacity := AbsoluteOpacity; (*remark this line ***************** Layout.HorizontalAlign := Grid.TextSettingsControl.ResultingTextSettings.HorzAlign; *) Layout.HorizontalAlign := HorizontalAlign;//add this line ***** 

Finally, you can set a new property in your project. eg:

MyColumn.HorizontalAlign: = TTextAlign.taCenter;

0
source

The "suat dmk" solution works fine, you have to recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas if you intend to use DB links.

After that, you simply add the OnPainting event:

 SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading; 
0
source

All Articles