Custom Cell

Cell body

ReoGrid provides an interface called cell body that supports to create customize cell. 

Cell Body

Cell body can be set into cell, uses cell’s size and accesses cell’s resource. 

Cell Body

Sample

A sample of a cell body that displays the red progress bar inside cell.

23 (1)

tip_s More samples available in demo project.

Interface of cell body

A custom cell body must inherit from CellBody or implement from ICellBody. The CellBody class provides many methods that can be overridden.

Before using this class, make sure that the following namespaces have been imported:

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

Definition of 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; }
}

Set cell body into cell

Use one of following method to set cell body into cell:

sheet["C3"] = new MyCellBody();
// or
sheet.Cells["C3"].Body = new MyCellBody();

Remove cell body from cell

Set Body property of cell instance to null to remove cell body:

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

Create own cell body

Make class inherit from CellBody, and add its instance onto worksheet.

// define
private class MyCellBody : CellBody
{
  public MyCellBody() {
  }
}

// use
sheet["C3"] = new MyCellBody();

tip_sAccording to the design of cell body, multiple cells can hold same instance of a cell body, usually one cell body can only set into one cell.

Owner Drawing

By overriding the OnPaint method to draw something inside cell.

private class MyCellBody : CellBody
{
  public override void OnPaint(RGDrawingContext dc)
  {
    // draw an ellipse inside cell
    dc.Graphics.DrawEllipse(Pens.Blue, base.Bounds);
  }
}

Bounds property is the boundary of cell body that is managed by worksheet automatically.

25 (1)

Recall core methods to draw cell text and background

To recall core methods to draw text and background, use following method of drawing context:

dc.DrawCellBackground();   // recall to draw cell background
dc.DrawCellText();         // recall to draw cell text

Typical flow to draw a custom cell body

There is the typical flow to draw a custom cell body.

// 1. call core method to draw cell background
dc.DrawCellBackground();

// 2. do custom drawing
dc.Graphics.Draw...();

// 3. call core method to draw cell text
dc.DrawCellText();

Sample of drawing cell text after custom drawing

382

Example: draw diagonal line inside cell

Below is an example to draw diagonal lines inside cell. Make the custom cell body:

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

  public DiagonalLineCell() { this.FromTopLeft = true; }

  public override void OnPaint(unvell.ReoGrid.RGDrawingContext dc)
  {
   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));
  }
}

Add two instances into worksheet:

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

The result:

185

Disable cell edit

By overriding OnStartEdit method and return false to prevent the default edit operation.

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

Change edit result

By overriding OnEndEdit method and return data to replace the user edit result.

Handle mouse and keyboard events

By overriding such as OnKeyDown and OnMouseDown methods to handle the keyboard and mouse events.

public override bool OnMouseDown(CellMouseEventArgs e)
{
  // translate cursor position to percent
  int value = (int)Math.Round(x * 100f / (Bounds.Width));

  // update cell's data, but do not set the data to cell directly, call methods of control instead
  sheet.SetCellData(e.CellPosition, value);
}

26 (1)

Data bind by using formula

It is possible to bind two cell’s data by using formula:

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

27 (1)

Built-in cell types

ReoGrid provides many built-in cell types such as Button, Check box, Drop-down list, Image and etc. See Built-in Cell Types.


Next: Iterate Cells