我用了一个类来表示StringGrid的额外信息比如这样这样:
TCellInfo = Class(TObject)
CellName: Tstring;
CellColor: TColor;
CellFont : TFont;
end;
利用StringGrid的Objects属性指向他,然后就可以用
TCellInfo(StringGrid1.Objects[Col,Row]).CellName来访问额外属性了.
但是绝大多数单元格的属性都是一样的,因此没必要为每个单元格都Create一个CellInfo;当没创建时,我希望能用缺省值来替代.
当想要给某个单元格起个名字时就要这样做:
if not assigned(StringGrid1.Objects[col,row]) then
begin
CellInfo := TCellInfo.Create;
StringGrid1.Objects[Col,Row] := CellInfo;
end;
TCellInfo(StringGrid1.objects[Col,Row]).CellName := 'abc'; 真的很麻烦,我希望不管他是不是nil,都能直接用
TCellInfo(StringGrid1.objects[Col,Row]).CellName := 'abc' ;
TCellInfo(StringGrid1.objects[Col,Row]).CellColor := clWhite;
赋值;也就是把上面的Create包装起来,怎么才能做到?
我想来想去都想不到有什么办法,只好都Create了,这样才能随意赋值而不出错,太浪费了。
TCellInfo = Class(TObject)
CellName: Tstring;
CellColor: TColor;
CellFont : TFont;
end;
利用StringGrid的Objects属性指向他,然后就可以用
TCellInfo(StringGrid1.Objects[Col,Row]).CellName来访问额外属性了.
但是绝大多数单元格的属性都是一样的,因此没必要为每个单元格都Create一个CellInfo;当没创建时,我希望能用缺省值来替代.
当想要给某个单元格起个名字时就要这样做:
if not assigned(StringGrid1.Objects[col,row]) then
begin
CellInfo := TCellInfo.Create;
StringGrid1.Objects[Col,Row] := CellInfo;
end;
TCellInfo(StringGrid1.objects[Col,Row]).CellName := 'abc'; 真的很麻烦,我希望不管他是不是nil,都能直接用
TCellInfo(StringGrid1.objects[Col,Row]).CellName := 'abc' ;
TCellInfo(StringGrid1.objects[Col,Row]).CellColor := clWhite;
赋值;也就是把上面的Create包装起来,怎么才能做到?
我想来想去都想不到有什么办法,只好都Create了,这样才能随意赋值而不出错,太浪费了。
可以用个函数
function SetCell(Col, Row: integer; val: string): boolean;
..
将代码移到里面
来操作,然后,你就可调用这个函数来设置!如果你想追求完美,你考虑用设计模式
Flyweight
uses Grids;
type
TCellInfo=class
end;
TMyGrid=class(TStringGrid)
public
procedure SetInfo(const Col,Row:integer;const Val:TCellInfo);
function GetInfo(const Col,Row:integer):TCellInfo;
property CellInfo[const Col,Row :integer]:TCellInfo read GetInfo write SetInfo;
end;
implementation{ TGrid }function TMyGrid.GetInfo(const Col, Row: integer): TCellInfo;
begin
if Objects[Col,Row]=nil then
Objects[Col,Row]:=TCellInfo.Create;
result:=TCellInfo(Objects[Col,Row]);
end;procedure TMyGrid.SetInfo(const Col, Row: integer; const Val: TCellInfo);
begin
if Objects[Col,Row]<>nil then
Objects[Col,Row].Free;
Objects[Col,Row]:=Val;
end;
CellInfo.Name := abc;
还是
AName := CellInfo.Name;
调用的都是GetInfo,也就是都Create了.
Objects中的数组元素全部指向同一个缺省的TCellInfo对象.
当修改TCellInfo的属性时,如果它是缺省对象,需要新建一个对象,再操作它.
CellInfo.Name := abc;
还是
AName := CellInfo.Name;
调用的都是GetInfo那么我如何知道用户是读还是写呢?
关键就是解决判断是读还是写的问题。
》列数改变时就全部创建好。这样比较省事。如果表格行列变动不频繁或者行数永远不会太
》多,甚至都用不到指针,直接用行列号做数组下标。不同意你的说法。Record不可以加方法(成员函数)不加的话,直接对内存地址赋值,在Grid上看不到的,要刷新!》对了,在我上面说的个人做法中,如果不直接用行列号做数组下标,就用Objects属性记录
》下标,不能记录数组元素的地址,因为数组的地址在重新分配内存时会改变,什么意思啊?我不明白,那岂不是不能用指针了?再说,如果用了数组,我记录下标来干什么?
"在Grid上看不到的,要刷新!"
当然是每次改动之后都要调用一下Invalidate,或者像你说的,再将需要显示的内容填入表格。(我觉得这是多余的浪费资源,实际上我根本不用StringGrid,用的是TDrawGrid)。“用了数组,我记录下标来干什么?”把数组的下标看作一种指针不行么? 为什么需要,因为视具体应用、程序写法,表格的行列不一定跟数组的元素顺序对应。我本来就声明这是“个人习惯”(这也说明当然是可行的。),仅供参考。不管如何,不该说什么“不同意”。
我说不同意,并没有贬低你的意思,也仅仅是我个人的看法,开了帖子,当然希望大家多来讨论,我一直都是尊敬回答问题的人的。
之所以不同意你的看法,也只限于这个个例,因为我做的是控件,不希望把刷新的事情让给用户做。