【问题标题】:Firemonkey Grid Control - Aligning a column to the rightFiremonkey Grid Control - 将列向右对齐
【发布时间】:2012-02-12 16:37:31
【问题描述】:

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

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

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

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.

亲切的问候。伊恩。

【问题讨论】:

    标签: delphi grid delphi-xe2 firemonkey


    【解决方案1】:

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

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

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

    您的列不需要 Create 方法(它什么都不做),所以删除它(除非您需要它来做其他事情)并修改您的 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;
    

    【讨论】:

    • 谢谢 Mike - 我一直在寻找的“完美答案”;一个真正的超级巨星..!
    【解决方案2】:

    我认为这是Embarcadero的懒惰。

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

    我建议不要修改原始 FMX.Grid 文件,而是将原始 FMX.Grid 文件复制到您的项目目录中,包括在您的项目中(添加到项目)并添加/修改以下行。

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

    最后,您可以在项目中设置新属性。例如:

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

    【讨论】:

      【解决方案3】:

      降序列不适用于实时绑定,因为绑定管理器会创建列,因此您必须将其降序处理。在我看来既不优雅也不实用。

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

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

      【讨论】:

        【解决方案4】:

        如果您在自定义正在创建的列类的机会较少时使用实时绑定,但您可以为 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);
        

        【讨论】:

          【解决方案5】:

          “suat dmk”的解决方案运行良好,如果您要使用 DB 链接,您必须 recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas

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

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

          【讨论】:

            【解决方案6】:

            另一种解决方案:

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

            【讨论】:

            • 解释,发布的代码的作用以及它如何解决问题中的问题,很少不能改善答案。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-31
            相关资源
            最近更新 更多