Delphi 10.1 BerlinのFireMonkeyアプリケーションでTStringGridでカスタムエディタを使用する

TStringGridのセルに入力するエディタをカスタマイズする方法を紹介します。

TStringGridでカスタマイズしたエディタを使用するには

エディタをカスタマイズするには、TStringGridのOnCreateCustomEditorイベントを使用します。
OnCreateCustomEditorイベントで、カスタマイズしたエディタを返します。

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    StringColumn1: TStringColumn;
    procedure StringGrid1CreateCustomEditor(Sender: TObject;
      const Column: TColumn; var Control: TStyledControl);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

procedure TForm1.StringGrid1CreateCustomEditor(Sender: TObject;
  const Column: TColumn; var Control: TStyledControl);
begin
  // ここでカスタマイズしたエディタを返す
  Control := TMyEdit.Create(Sender as TComponent);
end;

カスタマイズしたエディタを作成する

入力した文字を大文字に変換するカスタムエディタのサンプルです。
TMyEditは入力された値を大文字に変換します。

TEditクラスを継承したTMyEditクラスを作成します

type
  TMyEdit = class(TEdit)
  public
    constructor Create(AOwner: TComponent); override;
  end;

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;
end;

ICellControlインターフェースも継承します。

セルの編集が終わった後、列オブジェクト(TColumn)に対してセルの値の変更を通知する必要があります。
ICellControlインターフェースを継承すると、編集する列のオブジェクトを取得できるようになります。

type
  TMyEdit = class(TEdit, ICellControl)
  public
    constructor Create(AOwner: TComponent); override;
  end;

インターフェースが要求するメソッドを追加します。

type
  TMyEdit = class(TEdit, ICellControl)
  private
    [Weak]
    FColumn: TColumn;
    { ICellControl }
    function GetColumn: TColumn;
    procedure SetColumn(const Value: TColumn);
  end;

function TMyEdit.GetColumn: TColumn;
begin
  // 編集対象の列
  Result := FColumn;
end;

procedure TMyEdit.SetColumn(const Value: TColumn);
begin
  // 編集対象の列
  FColumn := Value;
end;

セルの値が変更されたら、列オブジェクトに変更を通知します。

type
  TMyEdit = class(TEdit, ICellControl)
  private
    procedure ChangeProc(Sender: TObject);
    ...
  end;

procedure TMyEdit.ChangeProc(Sender: TObject);
begin
  // 列に対して変更を通知する。これがないと編集した値が登録されない
  if FColumn <> nil then
    FColumn.EditorModified;
end;

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;
  // 入力されたらChangeProc処理を行う
  OnChangeTracking := ChangeProc;
end;

入力された値を大文字に変換する処理を追加します。

type
  TMyEdit = class(TEdit, ICellControl)
  private
    procedure ValidateText(Sender: TObject; var Text: string);
    ...
  end;

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;
  // 入力されたらChangeProc処理を行う
  OnChangeTracking := ChangeProc;
  // 入力が終わったときにValidateText処理を行う
  OnValidate := ValidateText;
end;

procedure TMyEdit.ValidateText(Sender: TObject; var Text: string);
begin
  // 入力が終わったら大文字に変換する
  Text := UpperCase(Text);
end;

以上で完成です。

全体のコードは次のようになります。

type
  TMyEdit = class(TEdit, ICellControl)
  private
    [Weak]
    FColumn: TColumn;
    procedure ChangeProc(Sender: TObject);
    { ICellControl }
    function GetColumn: TColumn;
    procedure SetColumn(const Value: TColumn);
    procedure ValidateText(Sender: TObject; var Text: string);
  public
    constructor Create(AOwner: TComponent); override;
  end;

{ TMyEdit }

procedure TMyEdit.ChangeProc(Sender: TObject);
begin
  // 列に対して変更を通知する。これがないと編集した値が登録されない
  if FColumn <> nil then
    FColumn.EditorModified;
end;

constructor TMyEdit.Create(AOwner: TComponent);
begin
  inherited;
  // 入力されたらChangeProc処理を行う
  OnChangeTracking := ChangeProc;
  // 入力が終わったときにValidateText処理を行う
  OnValidate := ValidateText;
end;

function TMyEdit.GetColumn: TColumn;
begin
  // 編集対象の列
  Result := FColumn;
end;

procedure TMyEdit.SetColumn(const Value: TColumn);
begin
  // 編集対象の列
  FColumn := Value;
end;

procedure TMyEdit.ValidateText(Sender: TObject; var Text: string);
begin
  // 入力が終わったら大文字に変換する
  Text := UpperCase(Text);
end;

サンプルアプリケーション

フォームにTStringGridを配置し、TStringColumnを追加します。

グリッドのOnCreateCustomEditorイベントを追加します。

procedure TForm1.StringGrid1CreateCustomEditor(Sender: TObject;
  const Column: TColumn; var Control: TStyledControl);
begin
  Control := TMyEdit.Create(Sender as TComponent);
end;

アプリケーションを実行します。

セルに入力します。

001

入力を完了すると、セルに入力した値が大文字に変換されます。

002

ソースコードのダウンロードはこちら→GridCustomEditor

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください