cxGrid で特定の行をロックし、編集を禁止する方法

概要

cxGrid コンポーネントは、デフォルトで全てのセルが編集可能な状態になっています。しかし、特定の条件下で、ある列の値に基づいて特定の行全体をロックし、編集不可にする必要がある場合があります。本記事では、その実現方法を解説します。

行全体の編集を禁止する

行全体の編集を禁止するには、主に TcxCustomGridTableViewOnEditing イベントを使用します。このイベントは、ユーザーがセルを編集しようとした際に発生し、AAllow パラメータを False に設定することで編集をキャンセルできます。

以下は、特定の条件(例:ステータス列の値が「完了」の場合)に基づいて行をロックするコード例です。

procedure TForm1.cxGrid1DBTableView1Editing(Sender: TcxCustomGridTableView;
  AItem: TcxCustomGridTableItem; var AAllow: Boolean);
var
  StatusValue: Variant;
begin
  // ステータス列の値を取得
  StatusValue := Sender.Controller.FocusedRecord.Values[cxGrid1DBTableView1Status.Index];
  
  // ステータスが「完了」の場合、編集を禁止
  if VarToStrDef(StatusValue, '') = '完了' then
    AAllow := False;
end;

行を編集不可に見せる

行を編集不可にする他の方法として、以下の2つのイベントを組み合わせることも可能です。

  • OnInitEdit イベント: 編集コントロールを「読み取り専用」に設定します。
  • OnStylesGetContentStyle イベント: 行のスタイルを「無効」なスタイルに変更し、見た目上也えを無効に見せます。

これらのイベントを使用したコード例は以下の通りです。

// 行を編集不可(読み取り専用)にする
procedure TForm1.cxGrid1DBTableView1InitEdit(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem;
  AEdit: TcxCustomEdit);
var
  StatusValue: Variant;
begin
  StatusValue := Sender.Controller.FocusedRecord.Values[cxGrid1DBTableView1Status.Index];
  if VarToStrDef(StatusValue, '') = '完了' then
    AEdit.Properties.ReadOnly := True;
end;

// 行を無効なスタイルにする
procedure TForm1.cxGrid1DBTableView1StylesGetContentStyle(
  Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
  AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
var
  StatusValue: Variant;
begin
  StatusValue := ARecord.Values[cxGrid1DBTableView1Status.Index];
  if VarToStrDef(StatusValue, '') = '完了' then
    AStyle := cxGrid1DBTableView1DisabledStyle;
end;

編集モード中の行ロック

さらに、cxGrid でマウスを特定の行にロックし、上下に移動できないようにする方法もあります。これは、編集モードに入った際に現在の編集行以外の行にフォーカスを移動させないようにするものです。

この機能を実現するには、TcxCustomGridTableViewOnCanFocusRecord イベントを使用します。このイベントは、ユーザーがレコードにフォーカスを移そうとした際に発生し、AAllow パラメータを False に設定することでフォーカスを禁止できます。

以下は、編集モード中に現在の編集行以外の行にフォーカスを移動できないようにするコード例です。

var
  isEditingMode: Boolean = False;
  currentEditingRecordIndex: Integer = -1;

procedure TForm1.cxGrid1DBTableView1EnterEdit(Sender: TcxCustomGridTableView);
begin
  isEditingMode := True;
  currentEditingRecordIndex := Sender.Controller.FocusedRecordIndex;
end;

procedure TForm1.cxGrid1DBTableView1ExitEdit(Sender: TcxCustomGridTableView);
begin
  isEditingMode := False;
  currentEditingRecordIndex := -1;
end;

procedure TForm1.cxGrid1DBTableView1CanFocusRecord(
  Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
  var AAllow: Boolean);
begin
  if isEditingMode and (ARecord.RecordIndex <> currentEditingRecordIndex) then
    AAllow := False;
end;

タグ: cxGrid Delphi データグリッド

6月21日 20:02 投稿