Firemonkey网格控件 - 将列对齐到右侧

时间:2012-02-12 16:37:32

标签: delphi grid delphi-xe2 firemonkey

我正在使用FireMonkey Grid控件但在尝试右对齐列时遇到了一个持续的问题。从其他用户发布的帖子中,我设法创建了一个新的TColumn类型,将样式应用于此(文本为HorzAlign = taTrailing),理论上 - 认为这将是解决方案。这些值由OnGetValue函数提供给Grid控件。

然而问题是,虽然一开始它看起来不错,但如果你滚动条形/鼠标滚轮等,新的TColumn类型列似乎没有使用下面的方法/代码正确刷新。它可能是网格的错误/特征(或者我正在做的方式)。我试过.ReAlign等...;但无济于事。让网格重新排列的唯一方法是进行列调整大小 - 然后重新正确重绘?

下面的代码显示它是一个简单的TGrid,有2个cols,1个是标准StringColumn,1个是我的新StringColNum(应用了wuth右对齐)。 - 任何帮助,因为这是任何网格工作的基本要求。

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.

亲切的问候。伊恩。

6 个答案:

答案 0 :(得分:5)

所有这些都提醒我,我还没有写过关于此的博文。

无论如何,网格单元可以是TStyledControl的任何后代(基本上任何控件)。文本单元格的默认值是TTextCell,它只是一个TEdit。作为TEdit意味着更改对齐非常简单:只需更改TextAlign属性即可。不需要乱用风格(除非你真的想要)。

您的列需要在CreateCellControl方法中创建单元格。您实际上是在创建列的实例,这是您的主要问题。

你不需要为你的列创建方法(它什么都不做),所以删除它(除非你需要其他东西)并修改你的CreateCellControl。

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

最后,您的GetValue事件处理程序只需要返回值:

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;

答案 1 :(得分:0)

降序列不适用于livebindings,因为bindmanager会创建列,所以你必须搞砸降序。在我看来,既不优雅也不实用。

只需在网格OnPainting事件中对齐您的单元格。

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

答案 2 :(得分:0)

如果您在自定义正在创建的列类的机会较少时使用livebinding,但您可以为Column创建帮助程序,以设置单个单元格控件的某些属性。不太优雅,但简单而且有效:

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.

绑定填满网格后,您可以调用帮助程序:

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

答案 3 :(得分:0)

我认为这是Embarcadero的懒惰。

在FMX.Grid.pas中添加/修改3行解决了这个问题。

而不是修改原始FMX.Grid pas,我建议将原始FMX.Grid pas复制到您的Project目录,包括在您的Project(添加到Project)和添加/修改以下行。

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 *****

最后,您可以在项目中设置新属性。 e.g:

MyColumn.Horizo​​ntalAlign:= TTextAlign.taCenter;

答案 4 :(得分:0)

如果您要使用数据库链接,“suat dmk”的解决方案正常工作您必须... = (Button) view.findView(...);

之后,您只需输入OnPainting事件:

recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas

答案 5 :(得分:0)

另一种解决方案:

Grid1.ApplyStyleLookup();
MyCol1.DefaultTextSettings.HorzAlign:=TTextAlign.taCenter;