履歴はワークシートごとに ws.Actions(ActionManager)が保持します。
使う
using unvell.ReoGrid.Core;
if (ws.Actions.CanUndo) ws.Actions.Undo();
if (ws.Actions.CanRedo) ws.Actions.Redo();
Console.WriteLine(ws.Actions.UndoName); // 次に取り消される操作の名前
Console.WriteLine(ws.Actions.RedoName);
コントロールを使っている場合は control.Undo() / control.Redo() /
control.CanUndo / control.CanRedo が同じものを呼びます。
Ctrl+Z / Ctrl+Y は既定で配線されています。
編集を履歴に載せる
コアのミューテーションは履歴に依存しません。 記録したい操作を recorder で包みます。
// 通常のミューテーションを包むだけで履歴に載る
ws.RecordCell("値の入力", 0, 0, () => ws.SetNumber(0, 0, 100));
ws.RecordRange("書式の適用", RangePosition.Parse("A1:C10"), () =>
{
for (int r = 0; r < 10; r++)
ws.SetNumberFormat(r, 0, "#,##0");
});
| recorder | 対象 |
|---|---|
RecordCell(name, row, col, mutate) | 単一セル |
RecordRange(name, rect, mutate, parts) | 範囲 |
RecordAxis(name, target, rows, cols, mutate) | 行・列のメタ情報 |
RecordEdit(name, target, spec, mutate) | 対象を細かく指定する汎用形 |
包まずに直接 ws.SetNumber(...) を呼んだ場合、値は変わりますが履歴には載りません。
コントロール経由の操作はすべて内部で包まれているため、UI から行う編集は自動的に記録されます。
何が記録されるか
操作の前後でスナップショットを取り、その差分を記録します。
記録されるもの — セル(値・スタイル・数値書式・リッチテキスト・数式)、罫線、結合、 セル型、条件付き書式、行・列のメタ情報。
編集した範囲だけが記録対象になるため、コストは編集の大きさに比例します。 シート全体を走査することはありません。
挿入・削除
行や列の挿入削除は専用の処理になります。
- 挿入 — 逆操作(削除)で戻す
- 削除 — 削除される帯を使用範囲でクランプして捕捉し、戻すときに復元。
さらに全数式を走査して
#REF!を治癒する
複数の操作をまとめる
切り取り+貼り付けのように内部で 2 段階になる操作は、ActionGroup として
1 ステップにまとめられます。ユーザーから見れば Ctrl+Z 一回で両方が戻ります。
容量とイベント
ws.Actions.Capacity = 200; // 既定は 100
ws.Actions.Clear();
ws.Actions.Changed += () => Console.WriteLine("履歴が変わった");
bool hasHistory = ws.HasActions; // ActionManager を生成せずに判定
容量を超えると古いものから捨てられます。
ws.HasActions は ActionManager を生成せずに存在を判定します。ヘッドレスで
一度も編集していないシートでは、マネージャ自体が作られません。
コントロール側は HistoryChanged イベントで通知します。ツールバーの有効・無効の
切り替えに使ってください。
履歴に載らない操作
- アウトライン(グループ化・解除)
- ファイルの読み込み(ワークブックごと差し替わるため)
- 表示に関する操作(ズーム、フリーズ、スクロール)
シートごとに独立
履歴はワークシート単位です。シートを切り替えると、そのシートの履歴が対象になります。