【问题标题】:How to set text alignment for a specific column in firemonkey TGrid/TStringGrid?如何为firemonkey TGrid / TStringGrid中的特定列设置文本对齐?
【发布时间】:2019-07-20 10:05:39
【问题描述】:

在 firemonkey (RAD Studio 10.3) 中,我正在使用连接到数据库的 TStringGrid,并且我想更改特定列的文本对齐方式。我怎样才能做到这一点?更改 TextSettings 属性中的 HorzAlign,会更改所有列的对齐方式。

我在this page 中尝试了建议的解决方案,但没有奏效!在较新版本的 Firemonkey 中,以下解决方案代码会导致错误。

type TSpecificColumn = class(TColumn)
protected
  function CreateCellControl: TStyledControl;override;
end;

TColumn 类中没有 CreateCellControl 函数可以被覆盖了!这是我得到的错误:

在基类中找不到方法 CreateCellControl。

【问题讨论】:

    标签: delphi firemonkey tstringgrid rad-studio tgrid


    【解决方案1】:

    OnDrawColumnCell 和/或OnDrawColumnHeader 事件中,您可以为此目的使用TTextLayout。如以下示例所示,使用三种不同的对齐方式绘制单元格。绘制标题时也可以应用:

    uses
      ...
      fmx.textlayout;
    
    
    procedure TForm11.Grid1DrawColumnCell(Sender: TObject; const Canvas: TCanvas;
      const Column: TColumn; const Bounds: TRectF; const Row: Integer;
      const Value: TValue; const State: TGridDrawStates);
    var
      tl: TTextLayout;
      rf: TRectF;    // added
    begin
      tl := TTextLayoutManager.DefaultTextLayout.Create;
      try
        tl.BeginUpdate;
        try
          // added from here
          rf := Bounds;
          InflateRect(rf, -2, -2);
          if (TGridDrawState.Selected in State) or
             (TGridDrawState.Focused in State) or
             (TGridDrawState.RowSelected in State)
          then
            Canvas.Fill.Color := TAlphaColors.LightBlue
          else
            Canvas.Fill.Color := TAlphaColors.White;
    
          Canvas.FillRect(rf, 0, 0, [], 1);
          // added until here
    
          tl.TopLeft := Bounds.TopLeft;
          tl.MaxSize := PointF(Column.Width, Column.Height);
          tl.Font.Size := 15;
          tl.Text := 'Some text'; // Value
          case Column.Index of
            0: tl.HorizontalAlign := TTextAlign.Leading;
            1: tl.HorizontalAlign := TTextAlign.Center;
            2: tl.HorizontalAlign := TTextAlign.Trailing;
          end;
        finally
          tl.EndUpdate;
        end;
        tl.RenderLayout(Canvas);
      finally
        tl.Free;
      end;
    end;
    

    TTextLayout 有许多其他有用的选项和属性,所以我建议看一下文档。

    【讨论】:

    • 感谢您的精彩回答!除了一件事我不知道该怎么做之外,一切都运行得很好。正如我在问题中提到的,我的 StringGrid 连接到数据库表(通过 TBindSourceDB)以查看和编辑值。对于创建的 textlayout 的 text 属性,我这样做了:tl.Text := value.ToString; 但现在在每个单元格中我都有两个文本值。 This is the image.你有什么建议? @汤姆
    • 对于标题我也有这个问题。通过在OnDrawColumnHeader 事件中添加Column.Header := '';,标题就可以了。但是对于包含数据库值的单元格,我不知道!这些是image#1image#2 在解决标题问题之前和之后。
    • 对不起到这里。如果您可以向我提供内存数据集、数据绑定和.fmx 文件的相关部分(以确保我的设置相同),我可以进一步调查以重现问题。还包括您的 OnDrawColumnCell() 事件处理程序版本。
    • 我在重新绘制之前添加了一些代码来清除单元格。我让您为各种TDrawStates 选择背景颜色。这对于TGridTStringGrid 应该都可以正常工作,但如果不是,请提供我之前评论中概述的测试用例。
    • 感谢一百万!你的新代码成功了。此外,我将InflateRect(rf, -2, -2); 更改为InflateRect(rf, 0, 0); 以完全覆盖单元格中的先前值。另外,我在选项中启用了 AlternatingRowBackground,我必须考虑交替行的背景颜色。作为一种解决方案,我检查行索引是奇数还是偶数,我不知道这是正确的方法还是愚蠢的方法!
    【解决方案2】:

    除了已经确定的更改InflateRect(rf, 0, 0),以允许正确显示现有数据:

    改变

    tl.Text := 'Some text'; // Value line 
    

    tl.Text := [StringGrid name property].Cells[Column.Index,Row];
    

    这对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多