カスタムセル

ReoGridはカスタムセルタイプを作成するための ICellBody インターフェースと CellBody 基底クラスを提供しています。セルボディはセル内に埋め込まれ、セルの寸法に準拠し、レンダリング、マウス、キーボードイベントを処理します。

Cell Body

名前空間

using unvell.ReoGrid.CellTypes;
using unvell.ReoGrid.Events;
using unvell.ReoGrid.Rendering;

クイックスタート

CellBody を継承するクラスを作成し、必要なメソッドをオーバーライドしてセルにアタッチします。

class MyCellBody : CellBody
{
    public override void OnPaint(CellDrawingContext dc)
    {
        dc.DrawCellBackground();
        // Custom drawing here
        dc.DrawCellText();
    }
}

// Attach to a cell
sheet["C3"] = new MyCellBody();
// Or:
sheet.Cells["C3"].Body = new MyCellBody();

セルボディを削除します。

sheet.Cells["C3"].Body = null;

CellBody基底クラス

CellBody クラスはすべての ICellBody メンバーのデフォルト実装を提供します。必要なメソッドのみをオーバーライドしてください。

プロパティ

プロパティ説明
CellCell親セル(OnSetup 後に利用可能)

ライフサイクルメソッド

メソッド戻り値説明
OnSetup(Cell cell)voidボディがセルにアタッチされたときに呼び出される。ここで参照を保存
OnSetData(object data)objectセルデータが設定されたときに呼び出される。変更されたデータまたは元のデータを返す
OnStartEdit()bool編集モード前に呼び出される。false を返すと編集を防止
OnEndEdit(object data, EndEditReason reason)object編集終了後に呼び出される。変更されたデータまたは元のデータを返す
OnEditTextChanged(string text, bool textAppend)(string, string)編集中にテキストが変更されたときに呼び出される。(text, selectedText) または (null, null) を返す
OnEditKeyDown(string text, KeyCode e)string編集中にキーが押されたときに呼び出される。新しいテキストまたは null を返す
OnGotFocus()voidセルがフォーカスを取得したときに呼び出される
OnLostFocus()voidセルがフォーカスを失ったときに呼び出される
Clone()ICellBodyこのセルボディのコピーを作成

レンダリングメソッド

メソッド戻り値説明
OnPaint(CellDrawingContext dc)voidセルボディをレンダリング。デフォルトは背景+テキストを描画
DrawBackground(CellDrawingContext dc)voidデフォルトのセル背景を描画
GetBodyBounds()Rectangleセル内のボディ境界を取得(パディングを考慮)
GetTextAvailableBounds(style)Rectangleテキスト領域の境界を取得
CalcCellContentWidth(cell, width)floatコンテンツ幅を計算
CalcCellContentHeight(cell, height)floatコンテンツ高さを計算

マウスメソッド

すべて bool を返します。true を返すとイベントを消費し、false でデフォルト動作になります。

メソッド説明
OnMouseDown(CellMouseEventArgs e)マウスボタンが押された
OnMouseUp(CellMouseEventArgs e)マウスボタンが離された
OnMouseMove(CellMouseEventArgs e)マウスが境界内で移動した
OnMouseEnter(CellMouseEventArgs e)マウスが境界に入った
OnMouseLeave(CellMouseEventArgs e)マウスが境界を出た
OnMouseWheel(CellMouseEventArgs e)マウスホイールがスクロールされた(void)

キーボードメソッド

メソッド戻り値説明
OnKeyDown(KeyCode e)boolキーが押された。true を返すと消費
OnKeyUp(KeyCode e)boolキーが離された。true を返すと消費

動作プロパティ

プロパティデフォルト説明
DisableWhenCellReadonlybooltrueセルが読み取り専用のときにボディを無効化
AutoCaptureMouse()booltrueマウスダウン後にマウスイベントをキャプチャ

CellDrawingContext

CellDrawingContextOnPaint の描画サーフェスを提供します。

メンバー説明
CellCellレンダリングされるセル
GraphicsIGraphicsプラットフォーム非依存のグラフィックスコンテキスト
WorksheetWorksheet親ワークシート
DrawModeDrawMode現在のレンダリングモード
DrawCellBackground(bool calcScale)voidデフォルトのセル背景を描画
DrawCellText()voidデフォルトのセルテキストを描画

ContentCellBody基底クラス

コンテンツ領域を持つセルボディ(チェックボックスやラジオボタンなど)の場合、ContentCellBody を継承します。

メソッド説明
GetContentSize()推奨コンテンツサイズを返す(デフォルト: 17x17)
GetContentBounds()セルスタイルに基づいて配置されたコンテンツ境界を取得(HAlign/VAlign)
OnContentPaint(CellDrawingContext dc)コンテンツ領域を描画するためにオーバーライド

オーナー描画

楕円の描画

class EllipseCell : CellBody
{
    public override void OnPaint(CellDrawingContext dc)
    {
        var bounds = GetBodyBounds();
        dc.Graphics.DrawEllipse(Pens.Blue,
            new Rectangle(0, 0, bounds.Width, bounds.Height));
    }
}

25

デフォルトの背景とテキストの描画

DrawCellBackground()DrawCellText() を呼び出してデフォルトのレンダリングを含めます。

public override void OnPaint(CellDrawingContext dc)
{
    dc.DrawCellBackground();
    // Custom drawing between background and text
    dc.DrawCellText();
    // Additional drawing on top
}

382

対角線の描画

class DiagonalLineCell : CellBody
{
    public bool FromTopLeft { get; set; } = true;

    public override void OnPaint(CellDrawingContext dc)
    {
        var bounds = GetBodyBounds();
        if (FromTopLeft)
            dc.Graphics.DrawLine(Pens.Black, new Point(0, 0),
                new Point(bounds.Right, bounds.Bottom));
        else
            dc.Graphics.DrawLine(Pens.Black, new Point(0, bounds.Bottom),
                new Point(bounds.Right, 0));
    }
}

sheet["B2"] = new DiagonalLineCell();
sheet["D2"] = new DiagonalLineCell { FromTopLeft = false };

185

セル編集の無効化

OnStartEdit から false を返して編集を防止します。

class ReadOnlyBody : CellBody
{
    public override bool OnStartEdit() => false;
}

編集結果の変更

OnEndEdit から変更されたデータを返します。

class UpperCaseBody : CellBody
{
    public override object OnEndEdit(object data, EndEditReason reason)
    {
        if (data is string s)
            return s.ToUpperInvariant();
        return data;
    }
}

マウスイベントの処理

class ClickableProgressCell : CellBody
{
    public override bool OnMouseDown(CellMouseEventArgs e)
    {
        var bounds = GetBodyBounds();
        int value = (int)Math.Round(e.RelativePosition.X * 100f / bounds.Width);
        Cell.Worksheet.SetCellData(e.CellPosition, value);
        return true; // consume the event
    }

    public override void OnPaint(CellDrawingContext dc)
    {
        dc.DrawCellBackground();
        var bounds = GetBodyBounds();
        int value = Cell?.Data is int v ? v : 0;
        float width = bounds.Width * value / 100f;
        dc.Graphics.FillRectangle(new Rectangle(0, 0, width, bounds.Height),
            SolidColor.LightGreen);
        dc.DrawCellText();
    }
}

26 (1)

キーボードイベントの処理

class KeyHandlerCell : CellBody
{
    public override bool OnKeyDown(KeyCode e)
    {
        if (e == KeyCode.Space)
        {
            // Toggle value
            Cell.Data = !(Cell.Data is true);
            return true;
        }
        return false;
    }
}

数式によるデータバインディング

数式を使用して2つのセルのデータをバインドし、セルボディが別のセルに反応するようにします。

sheet["C3"] = new ClickableProgressCell();
sheet["C7"] = "=C3";  // C7 mirrors C3's value

27 (1)

データ変更の傍受

OnSetData をオーバーライドして、データが保存される前に検証または変換します。

class ClampedCell : CellBody
{
    public override object OnSetData(object data)
    {
        if (data is double d)
            return Math.Clamp(d, 0.0, 1.0);
        return data;
    }
}

セルボディの境界

ボディの境界はセルサイズからパディングを引いて計算されます。GetBodyBounds() メソッドはセルの左上隅を基準とした Rectangle を返します。

public override void OnPaint(CellDrawingContext dc)
{
    var bounds = GetBodyBounds();
    // bounds.X, bounds.Y = padding offset
    // bounds.Width, bounds.Height = available area
}

利用可能な領域を変更するには、セルのパディングスタイルを調整します。

sheet.Cells["C3"].Style.Padding = new PaddingValue(5, 5, 5, 5);

クラス階層

組み込みセルタイプはさまざまなレベルで CellBody を拡張しています。

ICellBody (interface)
  └─ CellBody (base class)
       ├─ ContentCellBody (content region with alignment)
       │    ├─ CheckBoxCell
       │    └─ RadioButtonCell
       ├─ ButtonCell
       │    └─ ImageButtonCell
       ├─ DropdownCell (abstract — panel infrastructure)
       │    ├─ DropdownListBaseCell
       │    │    ├─ DropdownListCell
       │    │    └─ ComboListCell
       │    ├─ ColumnDropdownListCell
       │    └─ DatePickerCell
       ├─ ProgressCell
       │    └─ NegativeProgressCell
       ├─ HyperlinkCell
       └─ ImageCell

関連トピック


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