Firemonkey grid control - styling a cell based on value (by calling the OnGetValue function)

I am looking for a recommended solution for styling a TGrid cell that is called by calling OnGetValue (which is called to draw cells). For the background, Mike's excellent response showed how easy it is to apply the tAlign property when creating a cell; but my next task is to colorize the contents of the cells.

Previous post / reply

The goal is to change the attributes of the cell (font, style, color, etc.) of the value that I am going to return as the cell "Value". In the example below; it will apply the style to the return value of the "Value" OnGetValue. It is entirely possible that we should do this using the FM style sheet; or can we go directly to the TText attributes? Ideally, both scenarios would be great - but at this point I will take any decision ... (; β†’

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. 

Thanks a lot in advance, Yang.

+7
source share
2 answers

First, an apology. In answer to your last question, CreateCellControl had to inherit to create the cell. I corrected my answer.

Regarding this question, I uploaded my blog to FireMonkey Cells - http://monkeystyler.com/blog/entry/firemonkey-grid-basics-custom-cells-and-columns - it covers the material from the previous answer and also covers the creation custom cell controls. You will need to read this before you arrive. I'll wait.

...

Back? Good.

Following the example of a blog post.

Except that I updated TFinancialCell to inherit directly from TTextCell (which, of course, is TEdit), which makes much more sense and is much simpler in style.

So update 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; 

Code for the above:

 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; 

Finally, update the GetValue event handler:

 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; 
+5
source

The code above is suitable for versions prior to XE4, but does not work for XE4 and XE5. The color and style of the text do not change.

This is the fixed code for XE4 and 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; 
+1
source

All Articles