Firemonkey 网格控制 - 将列右对齐
我正在使用 FireMonkey Grid 控件,但在尝试右对齐列时遇到持续的问题。从其他用户的帖子中,我设法创建了一个新的 TColumn 类型,对此应用了一种样式(文本为 HorzAlign=taTrailing),理论上 - 认为这将是解决方案。这些值由 OnGetValue 函数提供给网格控件。
然而问题是,虽然一开始看起来不错,但如果您滚动栏/鼠标滚轮等,新的 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.
亲切的问候。伊恩.
I am using the FireMonkey Grid control but have an on-going issue in trying to right align a column. From other users postings, I have managed to create a new TColumn type, apply a style to this (text as HorzAlign=taTrailing) and in theory - thought that this would be solution. The values are provided by the OnGetValue function to the Grid control.
The problem is however that although at first it looks OK, if you scroll the bar/mouse wheel etc. the new TColumn type column does not appear to refresh correctly using the method/code below. It could be a bug/feature of the Grid (or the way I am doing it). I have tried .ReAlign etc...; but to no avail. The only way to get the grid back in line is do a column resize for example - which then redraws correctly?
The code below shows that it is a simple TGrid, with 2 cols, 1 the standard StringColumn and 1 my new StringColNum (wuth right alignment applied). - Any help appreciated as this one is a basic requirement of any grid work.
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.
Kind regards. Ian.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
所有这些都提醒我,我还没有写关于此的博客文章。
无论如何,网格单元可以是 TStyledControl 的任何后代(基本上是任何控件)。文本单元格的默认值是 TTextCell,它只是一个 TEdit。作为 TEdit 意味着更改对齐方式非常简单:只需更改 TextAlign 属性即可。无需搞乱样式(除非您真的想要)。
您的列需要在 CreateCellControl 方法中创建单元格。您实际上正在创建列的实例,这是您的主要问题。
您的列不需要 Create 方法(它什么也不做),因此删除它(除非您需要它用于其他用途)并修改您的 CreateCellControl。
最后,您的 GetValue 事件处理程序只需返回值即可:
All of which reminds me that I still haven't written my blog post about this.
Anyway, a grid cell can be any descendant of TStyledControl (basically any control). The default for a text cell is TTextCell, which is simply a TEdit. Being a TEdit means changing the alignment is really easy: just change the TextAlign property. No need to mess with styles (unless you really want to).
Your column needs to create your cells in the CreateCellControl method. You're actually creating an instance of your column which is your main problem.
You don't need the Create method for your column (it's doing nothing), so delete it (unless you need it for something else) and amend your CreateCellControl.
Finally, your GetValue event handler needs do nothing more than return the value:
我认为这是内河码头的懒惰。
在 FMX.Grid.pas 中添加/修改 3 行解决了这个问题。
我建议不要修改原始的 FMX.Grid 路径,而是将原始的 FMX.Grid 路径复制到您的项目目录,包括在您的项目中(添加到项目)并添加/修改以下行。
最后您可以在项目中设置新属性。例如:
MyColumn.HorizontalAlign:=TTextAlign.taCenter;
I think it is a laziness of Embarcadero.
adding/modifying 3 lines in FMX.Grid.pas solves this problem.
instead of modifiying original FMX.Grid pas, I recommend copying original FMX.Grid pas to your Project directory, including in your Project (add to Project) and adding/modifiying following lines.
finally you can set the new property in your Project. e.g:
MyColumn.HorizontalAlign:=TTextAlign.taCenter;
降序列不能很好地与实时绑定配合使用,因为绑定管理器会创建列,因此您必须搞乱降序列。在我看来既不优雅也不实用。
只需在网格 OnPainting 事件中对齐单元格即可。
Descending columns does not work well with livebindings as the bindmanager creates the columns so you have to mess with descending that. Neither elegant nor practical in my view.
Simply align your cells in the grid OnPainting event.
如果您在自定义正在创建的列类的机会较少时使用实时绑定,但您可以为 Column 创建帮助程序,以设置各个单元格控件的某些属性。不太优雅,但简单有效:
绑定填充网格后,您可以调用助手:
If you use livebindings when you have less chance to customize the column class which is being created, but you can create helpers for Column which sets some attributes of individual cell controls. Not too elegant but simple and works:
After the binding has filled the grid, you can call the helpers:
“suat dmk”的解决方案工作正常,如果您要使用数据库链接,则必须重新编译 Fmx.Bind.DBLinks.pas 和 Fmx.Bind.Editors.pas 。
之后,您只需放入 OnPainting 事件:
Solution of "suat dmk" is working fine you have to
recompile Fmx.Bind.DBLinks.pas and Fmx.Bind.Editors.pas
if you are gonna use DB links.After that, you simply put in OnPainting event:
另一个解决方案:
another solution: