Delphi Firemonkey网格控件-基于值设置单元格样式(通过OnGetValue函数调用)
我正在寻找推荐的解决方案来设置由OnGetValue调用绘制的TGrid单元格的样式(调用它来绘制视图中的单元格)。作为背景,Mike给出了一个极好的回答,展示了如何在创建单元格时简单地应用tAlign属性;但我的下一个挑战是给细胞内容着色 目标是更改我将作为单元格“值”返回的值的单元格属性(字体、样式、颜色等)。在下面的例子中;它将对返回的OnGetValue“value”应用样式。这很可能是我们必须通过FM样式表来实现的;或者我们可以直接访问TText属性吗?理想情况下,这两种方案都很好-但在这个阶段,我将采取任何一种解决方案。。。(;-> 多谢各位,Delphi Firemonkey网格控件-基于值设置单元格样式(通过OnGetValue函数调用),delphi,grid,delphi-xe2,firemonkey,Delphi,Grid,Delphi Xe2,Firemonkey,我正在寻找推荐的解决方案来设置由OnGetValue调用绘制的TGrid单元格的样式(调用它来绘制视图中的单元格)。作为背景,Mike给出了一个极好的回答,展示了如何在创建单元格时简单地应用tAlign属性;但我的下一个挑战是给细胞内容着色 目标是更改我将作为单元格“值”返回的值的单元格属性(字体、样式、颜色等)。在下面的例子中;它将对返回的OnGetValue“value”应用样式。这很可能是我们必须通过FM样式表来实现的;或者我们可以直接访问TText属性吗?理想情况下,这两种方案都很好-
伊恩。首先,道歉。在我对你最后一个问题的回答中,CreateCellControl应该调用inherited来创建单元格。我已经修改了我的答案 关于这个问题,我已经在FireMonkey Cells上上传了我的博客帖子——它涵盖了上一个答案中的内容,也涵盖了创建自定义单元格控件。在继续之前,您需要阅读这些内容。我将等待 现在回来?很好 下面是博客文章中的示例 除此之外,我已经更新了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;
上面的代码对于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;
你能定义“基于值”吗?你的意思是说,如果值是负数,那么字体将是红色的吗?嗨,迈克,是的,请注意。我有两种情况,但都是相同的原则。一种情况是负数显示为红色,另一种情况是“加粗”列表中的项目(这是我的选择-由于非电网持有的细节;重要客户等。)提前感谢。伊恩。嗨,迈克-再次感谢你的例子;你确实是“TGrid大师”。博客帖子/董事会帖子非常优秀,呈现得也非常好。我已经按照您修改/编辑的示例,让粗体和红色的效果很好。-再次感谢;一位真正的绅士…!Ian。(顺便问一下,有没有办法右对齐列标题,以及使用相同的方法对财务列进行右对齐…)嗨,迈克-我注意到了一个与上述内容相关的小问题?在我滚动窗口之前,一切看起来都很好。当它滚动时,红色/粗体会脱线/同步。我不确定这是否是FM或其他东西的重新绘制问题?如果你的代码很好,我可以发布我的代码?-提前谢谢,伊恩。我的问题。样式需要从SetData方法重新应用,所以我已经更新了上面的代码来提取ApplyStyles方法,并从ApplyStyle、SetData和SetIsImportant调用它。至于标题,应该很容易。在您的列构造函数中添加if(Grid nil)和(Grid.FHeader nil),然后添加Grid.FHeader.Items[索引].TextAlign:=TTextAlign.alTrailing;-但是Fheader是一个私有成员,因此您必须子类TGrid来公开它。(而TColumn也不公开它-它的Header属性只是一个字符串,而不是一个THeader)。谢谢您的编辑;没问题。当我滚动时,我似乎仍然会遇到一个奇怪的问题。但是,当您滚动时,某些值偶尔会以粗体显示,那么如果您向上滚动-它们不是?我还必须将“ApplyStyling”更改为“TFinancialCell.ApplyStyling”;这是正确的吗?还是我导致了问题?-Thx Ian。
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;
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;