【问题标题】:Firemonkey Grid Control - Styling a Cell based on a value (via the OnGetValue function call)Firemonkey Grid Control - 根据值设置单元格样式(通过 OnGetValue 函数调用)
【发布时间】:2012-03-04 20:16:58
【问题描述】:

我正在寻找推荐的解决方案来设置由 OnGetValue 调用绘制的 TGrid 单元格的样式(调用它来绘制视图中的单元格)。作为背景,Mike 的出色回应展示了如何在创建单元格时简单地应用 tAlign 属性;但我的下一个挑战是为单元格内容着色。

Previous posting/answer

目标是更改我即将作为单元格“值”返回的值的单元格属性(字体、样式、颜色等)。在下面的例子中;它将对正在返回的 OnGetValue“值”应用样式。很可能我们必须通过 FM 样式表来做到这一点;或者我们可以直接获得 TText 属性吗?理想情况下,这两种情况都很好 - 但在这个阶段我会采取任何一种解决方案......(;->

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;
  published
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

function TStringColNum.CreateCellControl: TStyledControl;
begin
  Result:=TTextCell.Create(Self);
  TTextCell(Result).TextAlign := TTextAlign.taTrailing;
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);
begin
  if Col=0 then
    Value:='Row '+IntToStr(Row);

  if Col=1 then
    Value := 'Row '+IntToStr(Row);

// Apply style based on value ?

end;

end.

提前非常感谢, 伊恩。

【问题讨论】:

  • 你能定义“基于一个值”吗?你的意思是说,如果值为负,那么字体将是红色等?
  • 嗨,迈克 - 是的;发现。我有两种情况,但都是相同的原理。一种情况是负值显示为红色,另一种情况是“加粗”列表中的项目(我选择的项目 - 由于离网持有的详细信息;重要客户等......)。提前致谢。伊恩。

标签: delphi grid delphi-xe2 firemonkey


【解决方案1】:

首先,道歉。在我对您最后一个问题的回答中, CreateCellControl 应该调用继承来创建单元格。我已经修改了答案。

至于这个问题,我已经在 FireMonkey Cells 上上传了我的博客帖子 - http://monkeystyler.com/blog/entry/firemonkey-grid-basics-custom-cells-and-columns - 它涵盖了上一个答案中的内容,还涵盖了创建自定义单元格控件。在继续之前,您需要阅读该内容。我等着。

...

现在回来?很好。

从博文中的示例开始。

除了,我更新了 TFinancialCell 以直接从 TTextCell(当然是 TEdit)继承,这更有意义并且更简单的样式。

所以,更新 TFinancialCell:

type TFinancialCell = class(TTextCell)
  private
    FIsNegative: Boolean;
    FIsImportant: Boolean;
  protected
    procedure SetData(const Value: Variant); override;
    procedure ApplyStyle;override;
    procedure ApplyStyling;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property IsNegative: Boolean read FIsNegative;
    property IsImportant: Boolean read FIsImportant;
  end;

以上代码:

procedure TFinancialCell.ApplyStyle;
var T: TFMXObject;
begin
  inherited;
  ApplyStyling;
end;

procedure TFinancialCell.ApplyStyling;
begin
  if IsNegative then
    FontFill.Color := claRed
  else
    FontFill.Color := claBlack;
  Font.Style := [TFontStyle.fsItalic];
  if IsImportant then
    Font.Style := [TFontStyle.fsBold]
  else
    Font.Style := [];
  if Assigned(Font.OnChanged) then
    Font.OnChanged(Font);
  Repaint;
end;

constructor TFinancialCell.Create(AOwner: TComponent);
begin
  inherited;
  TextAlign := TTextAlign.taTrailing;
end;

procedure TFinancialCell.SetData(const Value: Variant);
var F: Single;
  O: TFMXObject;
  S: String;
begin
  S := Value;
  FIsImportant := S[1] = '#';
  if IsImportant then
    S := Copy(Value,2,MaxInt)
  else
    S := Value;

  F := StrToFloat(S);
  inherited SetData(Format('%m', [F]));
  FIsNegative := F < 0;
  ApplyStyling;
end;

最后,更新 GetValue 事件处理程序:

procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer;
  var Value: Variant);
var Cell: TStyledControl;
begin
  if Col = 0 then
    Value := Row
  else if Col = 1 then
  begin
    Value := FloatToStr(Data[Row]);
    if Value > 30 then
      Value := '#'+Value;
  end;
end;

【讨论】:

  • 嗨,迈克 - 再次感谢您的示例;你确实是“TGrid 大师”。博客文章/董事会帖子非常好,而且呈现得很好。我已经设法遵循您修改/编辑的示例,并使粗体和红色运行良好。 - 再次感谢;真正的绅士……!伊恩。 (PS。有没有办法使用与 TFinancial 列相同的方法来右对齐列标题......?)
  • 嗨,迈克 - 我注意到与上述有关的一个小问题?在我滚动窗口之前,一切看起来都很好。当它滚动时,红色/粗体不符合/同步。我不确定这是 FM 的重绘问题还是其他问题?如果你的代码没问题,我可以发布我的代码吗? - 提前谢谢,伊恩。
  • 我的错。样式需要从 SetData 方法重新应用,因此我更新了上面的代码以提取 ApplyStyles 方法并从 ApplyStyle、SetData 和 SetIsImportant 调用它。
  • 至于标题,应该很简单。在您的列构造函数中添加 if (Grid nil) 和 (Grid.FHeader nil) 然后 Grid.FHeader.Items[Index].TextAlign := TTextAlign.alTrailing; - 但是 Fheader 是一个私有成员,所以你必须继承 TGrid 才能公开它。 (而且 TColumn 也没有公开它 - 它的 Header 属性只是一个字符串,而不是 THeader)。
  • 感谢编辑;没问题。当我滚动时,我似乎仍然遇到一个奇怪的问题,但是当您滚动时,某些值偶尔会加粗,然后如果您向上滚动 - 它们不是吗?我还必须将“ApplyStyling”更改为“TFinancialCell.ApplyStyling”;这是正确的 - 还是我造成了这个问题? - 谢谢伊恩。
【解决方案2】:

上面的代码适用于 XE4 之前的版本,但对于 XE4 和 XE5 不起作用。文本的颜色和样式没有改变。

这是 XE4 和 XE5 的固定代码:

procedure TFinancialCell.ApplyStyling;
begin
  StyledSettings := [TStyledSetting.ssFamily, TStyledSetting.ssSize];
  if IsNegative then
    FontColor := claRed
  else
    FontColor := claBlack;
  Font.Style := [TFontStyle.fsItalic];
  if IsImportant then
    Font.Style := [TFontStyle.fsBold]
  else
    Font.Style := [];
  if Assigned(Font.OnChanged) then
    Font.OnChanged(Font);
  Repaint;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多