我需要动态更改 DBGRid 中某些列的位置。假设我需要将第 21 列放在第 10 位。我使用:
DBGrid.Columns[21].Index:=10;
但是,这也改变了数组本身,也就是说,下次我想访问这个列时,我需要编写 DBGrid.Columns[10],这使它有点不干净,我需要记住所有列的位置等. 有没有更简单的方法来重新定位列?如果在此位置更改期间数组索引不更改,那也很好。
处理该问题的一种简单方法是不按索引访问列,而是按字段名访问列。引入这样的方法:
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;
缺点是每次需要访问网格时都必须运行循环,从而导致小的延迟,因此如果速度很重要,您可以考虑其他选项。
你说的对。您必须跟踪列的位置。也许在一个单独的结构中,或者作为从 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;
// ...
结尾;
无论如何,对于那些(像我一样)到达此页面并寻找重新排列网格中列的方法的人:
type
THackAccess = class(TCustomGrid);
procedure TCustomGrid_MoveColumn(grid: TCustomGrid; fromCol, toCol: integer);
begin
THackAccess(grid).MoveColumn(fromCol+1, toCol+1);
end;
输入列从零开始。