我需要动态更改DBGRid中某些列的位置。假设我需要将第21列放在第10位。我使用:
DBGrid.Columns[21].Index:=10;
但是,这也改变了数组本身,这意味着,下次我想访问这个列时,我需要编写DBGrid.Columns [10],这使得它有点不干净,我需要记住这个位置所有列等。是否有更简单的方法来重新定位列? 如果在这个位置变化期间数组索引没有改变也是好的。
答案 0 :(得分:6)
解决问题的一种简单方法是不按索引访问列,而是通过fieldname访问列。介绍这样的方法:
function GetColumn(aGrid : TDBGrid; aFieldName : string) : TColumn;
var
I : integer;
begin
for I := 0 to DBGrid.Columns.Count-1 do
if aDBGrid.Columns[I].FieldName = aFieldName then
begin
Result := aDBGrid.Columns[I];
exit;
end;
Result := nil;
end;
缺点是每次需要访问网格时都必须运行循环,导致小延迟,因此如果速度至关重要,您可以考虑其他选项。
答案 1 :(得分:2)
你是对的。您必须跟踪列的位置。可能在单独的结构中,或作为从TCustomGrid派生的后代对象。
我保留了一个容器对象,其中我存储了列的大小,它们包含的数据类型,排序顺序,格式选项以及网格中的位置等。然后我有一个引用容器的自定义网格。
type
TpaGrid = class;
TpaColumnType = (ctText,ctDateTime,ctNumber,ctSize,ctPic,ctFileName);
TpaColumn = class(TCollectionItem)
private
FCaption: string;
FTitleFont: TFont;
FTitleAlignment: TAlignment;
FDataType : TPaColumnType;
FWidth: Integer;
FFont: TFont;
FColor: TColor;
FBackColor: TColor;
FAltBackColor: TColor;
FAlignment: TAlignment;
FPosition : integer;
FSortOrder : integer; // 0=no sort, 1=first, 2=second, etc...
FSortAscending : boolean;
// .... and many other interesting attributes
public
// ... published properties
end;
TpaColumnClass = class of TPaColumn;
TpaColumns = class(TCollection)
private
FGrid: TPaGrid;
// ... Getters and Setters, exposing the items as columns
public
constructor Create(grid:TPaGrid; ColumnClass: TPaColumnClass);
function AddColumn: TPaColumn;
// ... Load and Save procedures
// ... published properties
end;
TpaGrid = class (TStringGrid)
// ... overriden methods WMSize, DrawCell, ...
// ... getters and setters
private
FColumns : TpaColumns;
// ...
端;
答案 2 :(得分:1)
无论如何,对于那些(像我一样)到达此页面寻找重新排序网格中列的方法的人:
type
THackAccess = class(TCustomGrid);
procedure TCustomGrid_MoveColumn(grid: TCustomGrid; fromCol, toCol: integer);
begin
THackAccess(grid).MoveColumn(fromCol+1, toCol+1);
end;
输入列从零开始。