Firemonkey Grid Control - Aligning a column to the right

主宰稳场 提交于 2019-12-05 08:20:13

All of which reminds me that I still haven't written my blog post about this.

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

Your column needs to create your cells in the CreateCellControl method. You're actually creating an instance of your column which is your main problem.

You don't need the Create method for your column (it's doing nothing), so delete it (unless you need it for something else) and amend your CreateCellControl.

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

Finally, your GetValue event handler needs do nothing more than return the 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;

Descending columns does not work well with livebindings as the bindmanager creates the columns so you have to mess with descending that. Neither elegant nor practical in my view.

Simply align your cells in the grid OnPainting event.

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

If you use livebindings when you have less chance to customize the column class which is being created, but you can create helpers for Column which sets some attributes of 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);

I think it is a laziness of Embarcadero.

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

instead of modifiying original FMX.Grid pas, I recommend copying original FMX.Grid pas to your Project directory, including in your Project (add to Project) and adding/modifiying 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 the new property in your Project. e.g:

MyColumn.HorizontalAlign:=TTextAlign.taCenter;

Solution of "suat dmk" is working fine you have to recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas if you are gonna use DB links.

After that, you simply put in OnPainting event:

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

another solution:

Grid1.ApplyStyleLookup();
MyCol1.DefaultTextSettings.HorzAlign:=TTextAlign.taCenter;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!