aardio 文档

dotNet.ReoGrid 扩展库 - 自定义单元格

单元格主体

ReoGrid 提供了一个称为 ICellBody 的接口,用于创建自定义单元格。单元格主体可以嵌入到单元格中,它会自动适应单元格的尺寸并获取单元格的某些资源访问权限。单元格主体

当单元格主体被分配到单元格后,它会无缝集成到单元格中,自动适应单元格大小并与单元格的属性和方法交互。单元格主体集成

示例

这是一个在单元格内显示红色进度条的单元格主体示例。23 (1)

更多示例可在演示项目中查看。

单元格主体接口

要在 ReoGrid 中创建自定义单元格主体, 我们必须用 C# 代码编写一个继承自 CellBody 的类或实现 ICellBody 接口。CellBody 类提供了多种可重写的方法,用于自定义单元格的行为和外观。

CellBody 类作为自定义单元格主体的基类,封装了单元格自定义所需的通用功能和属性。

在 GitHub 上查看 CellBody 源代码

调用 C# CellBodyICellBody 前请确保导入以下命名空间:

using System;
using unvell.ReoGrid;
using unvell.ReoGrid.CellTypes;
using unvell.ReoGrid.Events;
using unvell.ReoGrid.Rendering;
using unvell.ReoGrid.Graphics;
using unvell.ReoGrid.Interaction;

这个框架通过利用 CellBody 类或 ICellBody 接口,为扩展 ReoGrid 单元格功能提供了结构化方法。

创建单元格主体

首先我们在 aardio 里调用 C# 编译一个程序集以创建自定义的 MyCellBody 类。 当然也可以在 C# 开发环境内编译。

直接运行下面的 aardio 代码将会创建程序集 ardio.ReoGrid.dll 。

import dotNet.ReoGrid.Compiler; 
var compiler = dotNet.ReoGrid.Compiler();

//引用程序集
compiler.Reference("System.Drawing");

//C# 源码
compiler.Source = /***

//请确保导入以下命名空间:
using System;
using unvell.ReoGrid;
using unvell.ReoGrid.CellTypes;
using unvell.ReoGrid.Events;
using unvell.ReoGrid.Rendering;
using unvell.ReoGrid.Graphics;
using unvell.ReoGrid.Interaction; 

namespace aardio.ReoGrid{  

    //让类继承 CellBody
    class MyCellBody : CellBody {

        public override void OnPaint(CellDrawingContext dc)
        {
                // Define the bounds for the ellipse. Here, it fills the entire cell.
                Rectangle ellipseBounds = new Rectangle(0, 0, base.Bounds.Width, base.Bounds.Height);

                // Draw an ellipse within the cell using the specified bounds
                dc.Graphics.DrawEllipse(SolidColor.Blue, ellipseBounds);
        }
    }
}
***/    
compiler.CompileOrFail("/aardio.ReoGrid.dll");

在上面的示例中我们实现了自定义绘图的单元格。

首先我们重写了自定义单元格主体类 MyCellBody 中的 OnPaint 方法。通过重写 OnPaint 方法,可以为单元格执行自定义绘图操作,如绘制形状、文本或图像,从而根据特定需求增强单元格的视觉表现。

OnPaint 方法中:

将单元格主体设置到单元格

要在 ReoGrid 中将自定义单元格主体嵌入到特定单元格,可以使用以下任一方法。这两种方法功能相同,但提供了不同的语法选项:

  1. 使用工作表对象的索引器:
sheet1["C3"] = MyCellBody();

这种方法利用工作表对象的索引器,允许直接将 MyCellBody(或任何继承自 CellBody 的类)的新实例分配给 C3 位置的单元格。

  1. 设置 Cell 对象的 Body 属性:
sheet1.Cells["C3"].Body = MyCellBody();

这种方法通过工作表的 Cells 属性访问 C3 位置的 Cell 对象,然后将单元格的 Body 属性设置为 MyCellBody 的新实例。

这两种方法都会用新的 MyCellBody 实例替换指定单元格中现有的单元格主体。确保 MyCellBody 是一个继承自 ReoGrid 的 CellBody 类的类,这样才能自定义单元格行为和外观。

在 aardio 中创建自定义单元格的完整示例代码如下:

import win.ui;
/*DSG{{*/
var winform = win.form(text="ReoGrid - 自定义单元格")
/*}}*/

import dotNet.ReoGrid; 
var grid = ReoGrid.ReoGridControl(winform);
var sheet1 = grid.CurrentWorksheet;

//用 $ 操作符内存加载 DLL,发布后生成独立 EXE,不再需要 aardio.ReoGrid.dll
var dll = dotNet.loadFile($"/aardio.ReoGrid.dll");

//导入 C# 名字空间
var gridUtil = dll.import("aardio.ReoGrid");

//加载自定义单元格
sheet1["C3"] = gridUtil.MyCellBody();

winform.show();
win.loopMessage();

运行以上 aardio 示例的的显示效果如下:

25

从单元格移除单元格主体

将单元格实例的 Body 属性设为 null 即可移除单元格主体:

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

绘制默认单元格文本和背景

要在自定义单元格主体的绘制逻辑中按照 ReoGrid 的默认行为渲染单元格背景和文本,可以调用以下方法:

dc.DrawCellBackground();   // 重绘单元格背景
dc.DrawCellText();         // 重绘单元格文本

这些方法应该从自定义 CellBody 类的 OnPaint 方法重写中调用。dc 参数指向传递给 OnPaint 方法的 CellDrawingContext 对象,它提供了单元格渲染的绘图表面和上下文。

在自定义 CellBody 类的 C# 代码中,可以这样使用这些方法:

public override void OnPaint(CellDrawingContext dc)
{
    // 绘制默认单元格背景
    dc.DrawCellBackground();

    // 自定义绘图逻辑

    // 在背景上绘制默认单元格文本
    dc.DrawCellText();

    // 可以继续添加其他自定义绘图逻辑
}

示例结果:382

示例:在单元格内绘制对角线

以下是在单元格内绘制对角线的 C# 代码示例:

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));
   }
  }
}

在 aardio 中将上面的两个实例添加到工作表中:

var dll = dotNet.loadFile($"/aardio.ReoGrid.dll");
var gridUtil = dll.import("aardio.ReoGrid");

sheet1["B2"] = gridUtil.DiagonalLineCell();
sheet1["D2"] = table.assign( gridUtil.DiagonalLineCell() ,{FromTopLeft=false} );

结果:185

禁用单元格编辑

在 C# 代码中通过重写 OnStartEdit 方法并返回 false 来阻止默认编辑操作。

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

修改编辑结果

通过重写 OnEndEdit 方法并返回数据来替换用户编辑结果。

处理鼠标和键盘事件

在 C# 代码中通过重写如 OnKeyDownOnMouseDown 等方法来处理键盘和鼠标事件。

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)

使用公式绑定数据

可以使用公式绑定两个单元格的数据:

sheet1["C7"] = "=E7";

27 (1)

内置单元格类型

ReoGrid 提供了许多内置单元格类型,如按钮、复选框、下拉列表、图像等。详见内置单元格类型

Markdown 格式