TStringGrid の使い方
概要
カラムをフォームデザイナで追加するには右クリックして [項目デザイナ] から "項目の追加" でカラムを追加します (単純に右クリックして [項目の追加] でも可)。
次に、カラムをコードで追加する方法について説明します。
VCL 版 TStringGrid では ColCount プロパティでカラムを増減できましたが、FMX 版 TStringGrid には ColCount プロパティはありません。代わりに ColumnCount プロパティがあるのですが、ReadOnly なプロパティであり、これを用いてカラムを増減させる事はできません。ではどうやってコードでカラムを追加するのかと言うと、
// カラムを 3 つ作成
StringGrid1.AddObject(TStringColumn.Create(StringGrid1));
StringGrid1.AddObject(TStringColumn.Create(StringGrid1));
StringGrid1.AddObject(TStringColumn.Create(StringGrid1));
// カラムヘッダを設定
StringGrid1.Columns[0].Header := 'フィールド1';
StringGrid1.Columns[1].Header := 'フィールド2';
StringGrid1.Columns[2].Header := 'フィールド3';
// データは 50 行
StringGrid1.RowCount := 50;
// データ (1 行目)
StringGrid1.Cells[0, 0] := 'aaaaa';
StringGrid1.Cells[1, 0] := 'bbbbb';
StringGrid1.Cells[2, 0] := 'ccccc';
|
このように、カラムコントロールとして TStringColumn を AddObject() してやります。行の追加方法や、セルへのアクセス方法は VCL 版と同様です。
カラムコントロールとセルコントロール
TStringGrid のカラムは TColumn から派生した TStringColumn で構成されています。これがカラムコントロールです。
行を追加すると、カラムコントロールにセルコントロール (VCL 版 TStringGrid で言うインプレースエディタ) が生成されます。
TStringGrid のカラムコントロールである TStringColumn が生成するセルコントロールは TTextCell で、
と定義されています。それならば、
procedure TForm1.Button1Click(Sender: TObject);
begin
TEdit(StringGrid1.Columns[0].CellControlByRow(0)).TextAlign := TTextAlign.taLeading;
TEdit(StringGrid1.Columns[1].CellControlByRow(0)).TextAlign := TTextAlign.taCenter;
TEdit(StringGrid1.Columns[2].CellControlByRow(0)).TextAlign := TTextAlign.taTrailing;
end;
|
このようなコードでセルのセンタリングや右寄せができそうですが、それはうまく動作しないでしょう。何故ならば、セルコントロールは表示されている範囲のものしか生成されない...つまり、見えていないセルの TextAlign は設定できないからです。上記コードだと、グリッドの 1 行目がスクロールアウトしている場合には、セルコントロールが存在しないためにエラーが発生してしまいます。
Assigned() を用い、セルコントロールの存在確認を行ってエラーが出ないようにしてもいいのですが、一旦スクロールアウトして消滅したセルコントロールはスクロールインした際に再生成される訳で、このタイミングで TextAlign を再度設定してやらなくてはなりません...あまりにも面倒ですね。
センタリングや右寄せをしたいのであれば、独自にカラムコントロールを定義してやります。
[10.1 Berlin 以前] |
{ TStringColumn_Center }
TStringColumn_Center = class(FMX.Grid.TStringColumn)
protected
function CreateCellControl: TStyledControl; override;
end;
{ TStringColumn_Right }
TStringColumn_Right = class(FMX.Grid.TStringColumn)
protected
function CreateCellControl: TStyledControl; override;
end;
...
{ TStringColumn_Center }
function TStringColumn_Center.CreateCellControl: TStyledControl;
begin
result := inherited;
TEdit(result).TextAlign := TTextAlign.taCenter;
end;
{ TStringColumn_Right }
function TStringColumn_Right.CreateCellControl: TStyledControl;
begin
result := inherited;
TEdit(result).TextAlign := TTextAlign.taTrailing;
end;
|
10.2 Tokyo 以降、Grid の構造が変わっていますので注意してください。
[10.2 Tokyo 以降] |
{ TStringColumn_Center }
TStringColumn_Center = class(FMX.Grid.TStringColumn)
protected
procedure BeforeDrawing(const Canvas: TCanvas); override;
end;
{ TStringColumn_Right }
TStringColumn_Right = class(FMX.Grid.TStringColumn)
protected
procedure BeforeDrawing(const Canvas: TCanvas); override;
end;
...
{ TStringColumn_Center }
procedure TStringColumn_Center.BeforeDrawing(const Canvas: TCanvas);
begin
inherited;
Layout.HorizontalAlign := TTextAlign.Center;
end;
{ TStringColumn_Right }
procedure TStringColumn_Right.BeforeDrawing(const Canvas: TCanvas);
begin
inherited;
Layout.HorizontalAlign := TTextAlign.Trailing;
end;
|
カラムの生成コードを以下のように記述します。
procedure TForm1.FormCreate(Sender: TObject);
begin
// カラムを 3 つ作成
StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); // 左寄せ
StringGrid1.AddObject(TStringColumn_Center.Create(StringGrid1)); // センタリング
StringGrid1.AddObject(TStringColumn_Right.Create(StringGrid1)); // 右寄せ
...
|
標準のカラムコントロールである TStringColumn の代わりに、独自に定義したセンタリング/右寄せ用のカラムコントロールを使ってカラムを追加します。
TGrid も同じような考え方で機能拡張する事ができます。
セルコントロールを列単位で処理する
セルコントロールはカラムコントロール上に存在するので、列単位で何かやりたいのであれば、先に述べたように独自に定義したカラムコントロールを使って処理するのが簡単です。
特定の列だけ ReadOnly にするのは、カラムコントロールの ReadOnly プロパティを True に設定するだけでできます。
// カラムを 3 つ作成
StringGrid1.AddObject(TStringColumn.Create(StringGrid1));
StringGrid1.AddObject(TStringColumn.Create(StringGrid1));
StringGrid1.AddObject(TStringColumn.Create(StringGrid1));
// カラムヘッダを設定
StringGrid1.Columns[0].Header := 'フィールド1';
StringGrid1.Columns[1].Header := 'フィールド2';
StringGrid1.Columns[2].Header := 'フィールド3';
// 2 列目を ReadOnly に
StringGrid1.Columns[1].ReadOnly := True;
|
フォームデザイナでカラムを追加した場合には、カラムコントロールを選択すると、[オブジェクトインスペクタ] から ReadOnly プロパティを変更できます。
セルコントロールを行単位で処理する (10.1 Berlin 以前)
セルコントロールはカラムコントロール上に存在するので、行単位で処理をする事はできません。セルコントロールを一つずつ制御する必要があります。
uses
..., FMX.Edit;
procedure TForm1.StringGrid1SelChanged(Sender: TObject);
var
i: Integer;
Control: TStyledControl;
begin
// 10 行目をすべて ReadOnly にする
for i:=0 to StringGrid1.ColumnCount-1 do
begin
Control := StringGrid1.Columns[i].CellControlByRow(9); // 10 行目
if Assigned(Control) then
TEdit(Control).ReadOnly := True;
end;
end;
|
先に述べたように "セルコントロールは表示されている範囲のものしか生成されない" ので、Assigned を用いて必ず存在チェックを行う必要があります。
See Also: