学习一下在 FireMonkey 里面怎么用格子来实现一些界面效果。比如,类似 Delphi IDE 的属性面板那种格子。
一边学习一边写 Blog 作为记录。从最简单的玩法开始。
创建一个 FireMonkey 的工程,保存一下。只需要一个 Form。
拖一个 TLayout 过来,设置 Align 为 Top;拖一个 TGrid 到这个 Layout 里面,设置 Align 为 Left。
鼠标双击这个 Gird1,IDE 会弹出一个 Item Editor 窗口。这里点击 Add Item 按钮,增加一个 TColumn,它自动生成一个名字为 Column1 的 TColumn,也就是为这个 Grid 增加一个列。这里我要有两个列,另外一个列,我用代码创建。
先看看最终效果:
上述效果图里面,左边一列的数字,是行序号。右边一列的字符串,是用代码事先写死进一个 List 里面的。
代码里面写一点东西:
TForm1 = class(TForm)
Layout1: TLayout;
Grid1: TGrid;
Column1: TColumn;
procedure FormCreate(Sender: TObject);
procedure Grid1GetValue(Sender: TObject; const ACol, ARow: Integer;
var Value: TValue);
procedure Grid1SetValue(Sender: TObject; const ACol, ARow: Integer;
const Value: TValue);
private
{ Private declarations }
protected
ValueColumn: TColumn;
Data: TList<string>;
procedure PopulateData;
public
{ Public declarations }
end;
上述代码解释:
1. Data 用来存一些用于显示的文本数据。
2. ValueColunm 就是动态创建的列。
3. PopulateData 方法,用于为 Data 赋值。
procedure TForm1.PopulateData;
begin
Data := TList<string>.Create;
Data.Add('aaa');
Data.Add('bbb');
Data.Add('dfafasdfa');
Data.Add('bb3224b');
Data.Add('234234234');
Data.Add('-123423');
Data.Add('23423');
Data.Add('gfsdh adfa def');
end;
到这里可以开始正式写代码了。
首先在 Form OnCreate 里面写点代码,把数据创建出来,把另外一个列也创建出来。
procedure TForm1.FormCreate(Sender: TObject);
begin
PopulateData;
Grid1.RowCount := Data.Count;
ValueColumn := TColumn.Create(Grid1); //增加一列
ValueColumn.Parent := Grid1;
end;
解释:Grid1.RowCount := Data.Count; 这一行用于设置 Grid1 的行数。有多少条数据就给多少行。
格子创建好了,在哪里写代码把 Data 里面的文本写进这个 Grid1 里面去?在 Grid1 的 OnGetValue 事件里面。设计期鼠标选中 Grid1 后,在 IDE 属性面板的事件里面,找到 OnGetValue 双击,代码框架自动建立这个事件方法。里面写代码如下:
procedure TForm1.Grid1GetValue(Sender: TObject; const ACol, ARow: Integer;
var Value: TValue);
begin
if ACol = 0 then
Value := ARow
else if ACol = 1 then
Value := Data[ARow];
end;
上述代码解释:
1. ACol 代表当前的列数。0 = 第一列也就是左边列;1 = 第二列也就是右边列。
2. Value 代表当前格子的值。这里是 var 的说明可以赋值给它。
3. 当前是第一列,则给它 ARow 这个值,也就是当前的行号。
4. 当前是第二列,则给它 Data[ARow] 这个值,也就是当前行号对应的字符串列表的的第几条字符串。
试试看。
到这里,按 F9 可以运行程序看效果了。果然,格子出来了,显示了正确的内容。
鼠标点进某个格子,发现居然可以选中,还可以编辑里面的文字。但编辑文字后,一旦光标离开,编辑的文字丢失,还是显示原来的文字。
想了想,这里的代码显示的是 Data 里面的内容。那么,如果编辑后,把编辑的文字修改了 Data 里面对应的内容,应该就可以看到编辑结果不会丢失的效果。
既然把 Data 里面的内容显示到格子里是用 TGrid 的 OnGetValue 事件,那么,它应该有 OnSetValue 事件。去属性面板里面找了一下,果然有,双击它,自动出现代码框架,代码如下:
procedure TForm1.Grid1SetValue(Sender: TObject; const ACol, ARow: Integer;
const Value: TValue);
begin
if ACol = 1 then
begin
Data[ARow] := Value.ToString;
end;
end;
解释:
在这个事件方法里面,我写了 if ACol =1 then 意思是如果编辑的是对应的 Data 里面的数据,才保存当前编辑的数据到 Data 里面。对应的 ARow 行数也就是 Data 里面对应的 Index。
再次运行测试,界面上的 Grid1 里面,确实可以保留编辑结果了。
搞定。