V4 V5

CellTypeDescriptor を継承すると独自のセル型を作れます。描画は IGridGraphics に対して 行うため、WinForms / WPF / Avalonia / PDF のすべてで同じコードが動きます

このページで作る RatingCellType の描画結果

実装する

using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.CellTypes;
using unvell.ReoGrid.Core.Data;

/// <summary>値を 5 段階の丸で表示するセル型。</summary>
public sealed class RatingCellType : CellTypeDescriptor
{
	private readonly uint _color;

	public RatingCellType(uint color = 0xFFFFC107) => _color = color;

	public override string TypeName => "rating";

	// 丸を描くので、セルのテキストは描画しない
	public override bool ReplacesText => true;

	// 直接入力させず、クリックで値を変える
	public override bool AllowsTextEditing => false;

	public override bool Paint(in CellTypePaintContext ctx)
	{
		int filled = (int)Math.Clamp(ctx.Value.AsNumber, 0, 5);
		double size = Math.Min(ctx.Height - 4, 14);
		double y = ctx.Y + (ctx.Height - size) / 2;

		for (int i = 0; i < 5; i++)
		{
			double x = ctx.X + 3 + i * (size + 2);
			uint color = i < filled ? _color : 0xFFDDDDDD;
			ctx.Graphics.FillEllipse(x, y, size, size, color);
		}

		return true;   // 描画したので既定の処理は不要
	}

	public override CellTypeClickResult OnClick(in CellTypeClickContext ctx)
	{
		int star = (int)(ctx.LocalX / 16) + 1;
		return CellTypeClickResult.SetValue(CellValue.Number(Math.Clamp(star, 0, 5)));
	}

	// reogrid-json へ往復させるための設定値
	public override void WriteConfig(IDictionary<string, object?> config)
		=> config["color"] = _color;
}

オーバーライドできるメンバー

メンバー既定内容
TypeName(必須)保存時の型名。レジストリのキーになる
ReplacesTexttrueセルのテキスト描画を行わない
AllowsTextEditingtrueセルエディタでの直接入力を許すか
Paint(ctx)false描画。true を返すと既定の描画は行われない
OnClick(ctx)Unhandledクリック時の処理
OnActivate(ctx)UnhandledEnter キーなどでの起動時の処理
HitRegion(...)0ホバー領域の判定(複数の当たり判定を持つ場合)
WriteConfig(config)何もしない保存する設定値

描画コンテキスト

CellTypePaintContext が持つもの。

プロパティ内容
GraphicsIGridGraphics(描画先)
Row / Colセル位置
X / Y / Width / Heightセルの矩形(論理ピクセル)
Style実効スタイル
Valueセル値(CellValue
Text書式適用後の表示文字列
TextColor文字色
HoverRegionHitRegion が返した領域番号

MakeTextStyle(h, v) でセルのスタイルからテキスト描画用の設定を作れます。

クリックの結果

OnClick / OnActivate は抽象的な結果を返します。コアは UI を知らないため、 実際の動作はコントロール層が実体化します。

戻り値コントロールの動作
CellTypeClickResult.Unhandled何もしない
SetValue(value)セル値を更新(履歴にも載る)
OpenDropdown(options)ドロップダウンを表示
Navigate(url)既定のブラウザで開く
RaiseButton()CellButtonClicked を発火

使う

ws.SetCellType(RangePosition.Parse("C2:C100"), new RatingCellType());
ws.SetNumber(1, 2, 4);      // C2 に丸 4 つ

保存と復元

reogrid-json へ往復させるには、TypeName をキーにファクトリを登録します。

// 読み込み時に型名から復元できるようにする
CellTypeRegistry.Register("rating",
	config => new RatingCellType(config.GetColor("color") ?? 0xFFFFC107));

bool ok = CellTypeRegistry.IsRegistered("rating");

WriteConfig が書いた値が config として渡ります。取り出しには GetString / GetNumber / GetBool / GetColor / GetStringArray が使えます。

登録は CellTypeRegistry に対して行うためプロセス全体で共有されます。 アプリケーションの起動時、ファイルを読み込む前に済ませてください。 未登録の型名は読み込み時に無視されます(セル値は残ります)。

状態の持ち方

記述子にセルごとの状態を持たせないでください。 1 つの記述子が範囲全体で共有されるため、 インスタンスフィールドに状態を書くとすべてのセルで同じ値になります。

セルごとに変わるものはセル値に、範囲全体で共通の設定だけを記述子のフィールドに持たせます。

次に読む

ページの内容は役に立ちましたか?