カスタマイズしたセル型

ReoGrid はカスタマイズしたセル型を簡単に作成するためのインターフェイスを提供しています。カスタマイズしたセル型を利用するには、セルボディ(CellBody)クラスを利用します。セルボディはセルに格納でき、セルのデータやスタイルに簡単にアクセスすることができます。

Cell Body

セルボディのサイズはセルのサイズによって変化します。セルに Padding スタイルを設定した場合、Padding 部分を除いたサイズがボディのサイズになります。セルボディはセルのインスタンスを常に持っているため、セルのリソースに簡単にアクセスできます。また、セルボディはセルの操作も制御できます。

Cell Body

カスタマイズしたセル型のサンプル

下図にある左側の赤いバーは、カスタマイズしたセル型を利用したサンプルです。カスタマイズしたセル型を利用することで、様々な表現が実現できます。

23 (1)

デモプロジェクトには他のセル型のサンプルもあります。

セルボディのインターフェイス

カスタマイズしたセル型を作成するためには、セルボディクラスを作成する必要があります。セルボディのクラスはクラス CellBody 、またはインターフェイス ICellBody から継承する必要があります。CellBody クラスを継承した場合、必要なだけのメソッドをオーバーライドすれば、より簡単にセルボディを作成できます。

セルボディを作成するには、通常以下の通りの名前空間が必要です。

  • unvell.ReoGrid.CellTypes
  • unvell.ReoGrid.Rendering
  • unvell.ReoGrid.Events

CellBody クラスの定義は以下の通りです。

public class CellBody : ICellBody
{
  public ReoGridCell Cell { get; set; }
  public virtual void OnSetup(ReoGridCell cell) { }

  public virtual Rectangle Bounds { get; set; }
  public virtual void OnBoundsChanged() { }

  public bool AutoCaptureMouse() { return true; }

  public virtual void OnMouseDown(CellMouseEventArgs e) { }
  public virtual void OnMouseMove(CellMouseEventArgs e) { }
  public virtual void OnMouseUp(CellMouseEventArgs e) { }
  public virtual void OnMouseEnter(CellMouseEventArgs e) { }
  public virtual void OnMouseLeave(CellMouseEventArgs e) { }
  public virtual void OnMouseWheel(CellMouseEventArgs e) { }

  public virtual void OnKeyDown(KeyCode e) { }
  public virtual void OnKeyUp(KeyCode e) { }

  public virtual void OnPaint(CellDrawingContext dc) { }

  public virtual bool OnStartEdit() { return true; }
  public virtual object OnEndEdit(object data) { return data; }
  public bool DisableWhenCellReadonly { get { return true; } }
  public virtual object OnPaste(object data) { return data; }
  public virtual void OnGotFocus() { }
  public virtual void OnLostFocus() { }

  public virtual object OnSetData(object data) { return data; }
}

セルボディクラスの作成

MyCellBody クラスを作成して、CellBody から継承するように指定します。

class MyCellBody : CellBody
{
  public MyCellBody() {
    // 初期化処理
  }
}

セルボディをセルに格納する

以下のいずれかの方法でセルボディをセルに格納することができます。

sheet["C3"] = new MyCellBody();
// または
sheet.Cells["C3"].Body = new MyCellBody();

セルからセルボディを削除する

上記と同じ設定方法で、セルボディを null に設定するとセルから削除できます。

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

セルボディのカスタマイズ

親クラス CellBody に提供されている様々なメソッドをオーバーライドすると、カスタマイズした描画や操作制御を実現できます。

セルのインスタンスを取得する

CellBody クラスにセルのインスタンス Cell プロパティがあります。このプロパティを利用すればセルのインスタンスを取得できます。

ただし、Cell プロパティはセルボディをセルに格納している場合のみ有効になります。セルボディがセルに格納するタイミングが知りたい場合、以下のメソッドをオーバーライドします。

class MyCellBody : CellBody
{
  public override void OnSetup(ReoGridCell cell)
  {
    base.OnSetup(cell);

    // セルの表示中のテキストを取得する
    var text = cell.DisplayText;
  }
}

セルボディがセルから削除された場合、Cell プロパティが null になりますので、利用の際に null チェックを行うと安全です。

カスタマイズ描画

CellBody クラス OnPaint メソッドをオーバーライドすると、セルの描画をカスタマイズできます。

class MyCellBody : CellBody
{
  public override void OnPaint(CellDrawingContext dc)
  {
    // 青い円を描く
    dc.Graphics.DrawEllipse(Pens.Blue, base.Bounds);
  }
}

25 (1)

Bounds プロパティはセルボディの境界矩形です。このプロパティはセルボディがセルに格納された場合自動的に設定されます。

デフォルトの描画メソッドを呼び出す

カスタマイズ描画を行う際に、セルのデフォルトの描画関数を呼び出すことができます。セルのテキストまたは背景色を描画したい場合、以下の二つのメソッドを利用できます。

dc.DrawCellText();        // セルテキストの描画関数
dc.DrawCellBackground();  // セル背景色の描画関数

例えば、上記サンプルで描画した円形の中にセルテキストを表示したい場合、以下のようにソースコードを改修します。

class MyCellBody : CellBody
{
  public override void OnSetup(ReoGridCell cell)
  {
    base.OnSetup(cell);

    // セルのテキストを中央寄せに設定する
    cell.Style.HAlign = ReoGridHorAlign.Center;
  }

  public override void OnPaint(CellDrawingContext dc)
  {
    // 青い円を描く
    dc.Graphics.DrawEllipse(Pens.Blue, base.Bounds);

    // セルテキスト描画を呼び出す
    dc.DrawCellText();
  }
}

セルのテキストを円形の真ん中に表示するため、セルボディの OnSetup メソッドをオーバーライドし、セルテキストのアレンジメント設定を中央寄せに設定しました。

このセルボディをワークシートに格納するコードは以下の通りです。

sheet["C3"] = new MyCellBody();
sheet["C3"] = "123";

382

セルの編集操作を禁止する

OnStartEdit メソッドをオーバーライドし、false を返すとセルの編集操作を禁止することができます。

class MyCellBody : CellBody
{
  public override bool OnStartEdit()
  {
    return false;
  }
}

ユーザーの編集結果を変更する

OnEndEdit メソッドはセルの編集終了の時に呼び出されます。ユーザーの編集結果を変更したい場合、OnEndEdit メソッドをオーバーライドすると編集結果を変更することができます。

class MyCellBody : CellBody
{
  public override object OnEndEdit(object data)
  {
    string text = Convert.ToString(data);

    // データに - _ / \\ のいずれかが含まれる場合
    if (text.IndexOfAny(new char[] { '-', '_', '/', '\\' }) >= 0)
    {
      // データを null(空白) に変更する
      data = null;
    }

    return base.OnEndEdit(data);
  }
}

マウスとキーボードの入力制御を行う

マウスの入力制御に関するメソッドは以下の通りです。

メソッド名説明
OnMouseDownマウスボタンがセルの中で押下された場合
OnMouseMoveマウスがセルの中で移動された場合
OnMouseUpマウスボタンがセルの中でリリースされた場合
OnMouseEnterマウスがセルの外から中に移動された場合
OnMouseLeaveマウスがセルの中から外に移動された場合
OnMouseWheelマウスがセルの中でスクロールされた場合
AutoCaptureMouseこのメソッドからTrueを返した場合、マウスボタンが押下されてから及びリリースされるまでこのセルの中で移動することとみなす

キーボードの入力制御に関するメソッドは以下の通りです。

メソッド名説明
OnKeyDownキーボードが押下された場合
OnKeyUpキーボードがリリースされた場合

キーボードのメソッドが呼び出されるため、セルが焦点になっている(フォーカスされている)ことが必要です。

使用例:スライドバーを作成する

スライドバーを利用して、マウスでドラッグするだけで数値 0~1 の小数を入力することができます。マウスのドラッグによって数値を計算するためのソースコードは以下の通りです。

public override bool OnMouseMove(CellMouseEventArgs e)
{
  // マウスのX位置 / セルボディの幅 = 0~1の数値
  float value = e.RelativePosition.X / Bounds.Width;

  if (value < 0) value = 0;
  if (value > 1) value = 1;

  // 計算した結果をセルのデータに更新
  e.Worksheet.SetCellData(e.CellPosition, value);

  return true;
}

26 (1)

実行ファイルはデモプロジェクトをご参照ください。

数式を利用してデータを連動させる

数式を利用すれば、二つのセルのデータを連動させることもできます。

例えば以下の数式でセル C7 のデータを常に E7 から読み込むように連動させます。

sheet["C7"] = "=E7";

27 (1)

実行ファイルはデモプロジェクトをご参照ください。

内蔵セル型

ReoGrid では様々なセル型を提供しています。例えば標準形式のボタン、チェックボックス、ラジオボタン、ドロップダウンリストなど、詳しくは、「様々な入力方法とセル型」をご覧ください。


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