コントロールは 7 つのイベントを持ちます。WinForms / WPF / Avalonia で名前も引数も同じです。
| イベント | 発火するとき | 主な用途 |
|---|---|---|
SelectionChanged | 選択範囲・アクティブセルが変わった | 数式バー・ステータスバーの更新 |
WorkbookChanged | ワークブックが差し替わった | シートタブの作り直し |
ActiveSheetChanged | 表示シートが切り替わった | シートタブの選択状態 |
HistoryChanged | 履歴が変わった | Undo / Redo ボタンの有効・無効 |
ZoomChanged | 表示倍率が変わった | 倍率表示の更新 |
ContextMenuRequested | 右クリックされた | メニューの構築 |
CellButtonClicked | ボタンセル型が押された | 業務ロジックの実行 |
以下のサンプルは Avalonia 版で書いていますが、using を差し替えれば
WinForms 版・WPF 版でもそのまま動きます。
選択が変わった
using unvell.ReoGrid.Avalonia;
using unvell.ReoGrid.Core;
grid.SelectionChanged += (_, _) =>
{
CellPosition active = grid.ActiveCell;
RangePosition range = grid.Selection;
Console.WriteLine($"アクティブ {active.Row},{active.Col} / 選択 {range.Rows}×{range.Cols}");
};
数式バーを自作する場合は、このイベントで grid.GetActiveCellInput() を読み直します
(セルの編集)。
矢印キーでの移動、マウスでのドラッグ、MoveTo() の呼び出し — いずれも同じイベントが
発火します。「ユーザー操作か、コードからか」の区別は付きません。区別が必要な場合は、
コードから動かす前後でフラグを立ててください。
ワークブック・シートが変わった
// ワークブックごと差し替わったとき(NewWorkbook / LoadWorkbook / LoadJson)
grid.WorkbookChanged += (_, _) => Console.WriteLine($"シート {grid.Workbook.Count} 枚");
// 表示シートが切り替わったとき
grid.ActiveSheetChanged += (_, _) => Console.WriteLine(grid.ActiveWorksheet.Name);
シートタブを自作する場合、この 2 つを両方受けます。WorkbookChanged でタブを作り直し、
ActiveSheetChanged で選択状態を合わせます。
組込のシートタブ UI はありません。 タブが必要なら、grid.Workbook.Worksheets を
並べて grid.SetWorksheet(ws) を呼ぶ形で自作します。
履歴・表示倍率
// ツールバーの「元に戻す」「やり直す」の有効・無効を追随させる
grid.HistoryChanged += (_, _) =>
{
Console.WriteLine($"Undo={grid.CanUndo} Redo={grid.CanRedo}");
};
grid.ZoomChanged += (_, _) => Console.WriteLine($"{grid.Zoom:P0}");
ZoomChanged は Ctrl+ホイールによる変更でも発火します
(表示倍率)。
右クリック
組込のコンテキストメニューはありません。 右クリックされると
ContextMenuRequested が上がるだけなので、ホスト側でメニューを構築します。
プラットフォームごとにメニューの作り方が違うため、コアからは出せないためです。
grid.ContextMenuRequested += (_, e) =>
{
switch (e.Target)
{
case GridContextTarget.Cell: /* セル用のメニュー */ break;
case GridContextTarget.RowHeader: /* 行ヘッダー用(e.Index が行番号) */ break;
case GridContextTarget.ColumnHeader: /* 列ヘッダー用(e.Index が列番号) */ break;
case GridContextTarget.Corner: /* 左上の全選択ボタン */ break;
}
};
GridContextMenuEventArgs | 内容 |
|---|---|
Target | Cell / RowHeader / ColumnHeader / Corner |
Cell | クリック後のアクティブセル |
Index | ヘッダーの場合の行番号・列番号 |
ScreenLocation | メニューを出す位置 |
右クリックは選択を確定してからイベントを上げます。選択範囲の上で右クリックした 場合は選択が保たれ、範囲外なら 1 セル選択に切り替わります(Excel と同じ)。
ボタンセル型が押された
grid.CellButtonClicked += (_, e) =>
Console.WriteLine($"{e.Cell.Row},{e.Cell.Col}");
チェックボックス・ドロップダウン・ハイパーリンクはコントロールが自分で処理するため、 イベントは上がりません(セル型の基本)。
セル値が変わったことを知る
セル値の変更イベントはありません。 Worksheet は UI に依存しないモデルであり、
サーバー上で数十万セルを書き込む用途を含むため、書き込みごとにイベントを発火する
作りにはしていません。
代わりに 2 つの方法があります。
// セル値の変更イベントは無い。自分で書いた変更は書いた場所で拾える
void SetChecked(int row, bool value)
{
ws.RecordCell("チェック", row, 0, () => ws.SetBoolean(row, 0, value));
OnCellChanged(row, 0);
}
// UI からの編集は履歴に載るので、ここで拾う
ws.Actions.Changed += () => Console.WriteLine("シートが編集された");
SetChecked(0, true);
- 自分のコードによる変更 — 書いている場所で処理を呼びます
- ユーザーの編集 —
ws.Actions.Changed(コントロール側のHistoryChangedと同じ元) で拾えます。ただし通知されるのは「何かが変わった」ことだけで、 どのセルが変わったかは含まれません
変更されたセルを特定する必要がある場合は、SelectionChanged で編集開始位置を覚えておき、
HistoryChanged の時点でその位置を読み直すのが実用的です。