概要
cxGrid コンポーネントは、デフォルトで全てのセルが編集可能な状態になっています。しかし、特定の条件下で、ある列の値に基づいて特定の行全体をロックし、編集不可にする必要がある場合があります。本記事では、その実現方法を解説します。
行全体の編集を禁止する
行全体の編集を禁止するには、主に TcxCustomGridTableView の OnEditing イベントを使用します。このイベントは、ユーザーがセルを編集しようとした際に発生し、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 でマウスを特定の行にロックし、上下に移動できないようにする方法もあります。これは、編集モードに入った際に現在の編集行以外の行にフォーカスを移動させないようにするものです。
この機能を実現するには、TcxCustomGridTableView の OnCanFocusRecord イベントを使用します。このイベントは、ユーザーがレコードにフォーカスを移そうとした際に発生し、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;