如何找到网格列的顺序?

How can I find the order of grid columns?

我在连接到具有 10 个字段的数据库 table 的表单上有一个网格。第一个字段(隐藏)是 ID。第二个字段是 First_Name,第三个 Last_Name,等等。这些列的索引从 1 到 10。现在,如果用户想要 First_Name 之前的 Last_Name,他可以抓住那一列并将其滑过。 First_Name 现在拥有索引 3,Last_Name 位于索引 2。

我需要能够读取列索引的顺序,以便将它们写入 INI 文件。然后下次用户打开应用程序时,我可以将网格设置回首选状态。

我正在使用 TRxDBGrid 对 Lazarus 2.0.6 执行此操作。我已经尝试了它的几个属性,但其中 none 显示了网格列顺序。

我通常使用 Delphi 而不是 Lazarus,并且一直在尝试将 RXDbGrid 包安装到 Lazarus 2.0.6 中以检查我对此的建议答案,但到目前为止还没有成功。然而...

TRxColumn 源自 DBGrids 源文件中的 TColumn

TColumn有一个public属性Index是一个整数,它是列在GridColumnscollection中的索引。

因为我无法让 RXDBGrid 安装 atm,所以下面的示例使用了普通的 TDBGrid,但在进行明显的细节更改后应该可以正常工作。

示例有 3 个字段,ID 整数,名称字符串 [20] 和值整数。

为简单起见,不是保存和加载 IniFile,而是将列顺序保存到 TMemo,要测试 LoadColumnInfo 您需要更改备忘录中的列顺序。

如您所见,要重新加载网格列顺序,最简单的方法是按左->右顺序保存列标题,并在重新加载时使用函数 ColumnByName 找到正确的列保存的信息。

uses
  Classes, SysUtils, memds, db, Forms, Controls, Graphics, Dialogs, DBGrids,
  StdCtrls;

type
  TForm1 = class(TForm)
    btnSaveColumns: TButton;
    btnLoadColumns: TButton;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    MemDataset1: TMemDataset;
    Memo1: TMemo;
    procedure btnLoadColumnsClick(Sender: TObject);
    procedure btnSaveColumnsClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    function ColumnByName(const AName: String): TColumn;
    procedure LoadColumnInfo;
    procedure SaveColumnInfo;
  public
  end;
 [...]

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  i : integer;
begin
  MemDataSet1.Open;
  for i := 0 to 5 do
    MemDataSet1.InsertRecord([i, 'Name' + IntToStr(i), i]);
end;

procedure TForm1.btnSaveColumnsClick(Sender: TObject);
begin
  SaveColumnInfo;
end;

procedure TForm1.btnLoadColumnsClick(Sender: TObject);
begin
  LoadColumnInfo;
end;

procedure TForm1.SaveColumnInfo;
var
  i : Integer;
  S : String;
begin
  Memo1.Lines.Clear;
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
     S := DBGrid1.Columns[i].Title.Caption;
     Memo1.Lines.Add(S);
  end;
 end;

function TForm1.ColumnByName(const AName : String) : TColumn;
var
  i : integer;
begin
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
    Result := DBGrid1.Columns[i];
    if CompareText(AName, Result.Title.Caption) = 0 then
      exit;
  end;
  Result := Nil;
end;

procedure TForm1.LoadColumnInfo;
var
  i : Integer;
  Index : Integer;
  Column : TColumn;
  S : String;
begin

  for i := 0 to Memo1.Lines.Count - 1 do begin
    S := Memo1.Lines[i];
     Column := ColumnByName(S);
     Assert(Column <> Nil);
     Column.Index := i;
  end;
end;

end.