文档章节

Spread 之自定义对角线cellType源码: DiagonalCellType

文刚的技术博客
 文刚的技术博客
发布于 2014/08/07 15:15
字数 1278
阅读 31
收藏 0

最新的SpreadWinform提供了多达24种CellType类型,下面的这2篇博文对新增了GcTextBoxCellType和GcDateTimeCellType单元格格式做了比较详细的说明。

Spread 7 for WinForms 新增的GcTextBoxCellType (水印、自动换行、自动大写、长度限制等)

Spread 7 for WinForms 新增的GcDateTimeCellType (日期、时间格式)

一般常规的做法是通过LineShape来做,《Spread for Winforms 表格控件:实现交叉报表》 用LineShape进行了编码实践,使用效果反响不错。

 Spread_CrossReport

在实际项目中,有人提出,能否自定义一个CellType来实现而不是采用Shape方式呢?

答案是肯定的,下面我们来一一说明详细过程:

在实际项目中有如下三种需求---需要在Spread表头绘制对角线+表头文字:

region2 双区域对角线,定义枚举为:e2Region。

 

region3三区域对角线,定义枚举为:e3Region

 

 region4 四区域对角线,定义枚举为:e4Region

 

Step 1: 输入文字需求

  • 字体默认获取系统的

  • 斜线的颜色和宽度可自定义

  • 背景色和前景色可自定义

  • 可选择文字对齐方向,并对超出区域文字剪裁处理

  • 编辑CellType区域 

  • Step 2:依据文字需求,快速手绘原型:right

IMG_20131218_151539

在手绘原型过程中,产生过如下三种原型,在评审中被否决的:error

IMG_20131218_151521

主要是考虑到横线、竖线、斜对角线没有太多的使用场景,目前用不上。

Step 3:DiagonalCellType接口测试开发

自定义CellType的目的是方便使用,故依照TDD的编程思路,先通过接口测试开始第一步工作,方便用户和其他系统自带的CellType切换使用,且能复用Cell已有的BackColor、Font、ForeColor、CellPadding。

下面是双区域对角线的测试使用源码。(实际项目中,仅需要前4行源码即可实现双区域对角线的CellType使用)

  1:             //Diagonal_2Region
  2:             DiagonalCellType ct = new DiagonalCellType(DiagonalSubCellType.e2Region);
  3:             this.fpSpread1.ActiveSheet.Cells[1, 0].CellType = ct;
  4:             ct.SetText("产品", StringAlignment.Far);
  5:             ct.SetText("日期", StringAlignment.Near, StringFormatFlags.DirectionVertical);
  6:             this.fpSpread1.ActiveSheet.Cells[1, 0].BackColor = Color.Green;
  7:             this.fpSpread1.ActiveSheet.Cells[1, 0].Font = new Font("宋体", 12);
  8:             this.fpSpread1.ActiveSheet.Cells[1, 0].ForeColor = Color.Blue; //line
  9:             this.fpSpread1.ActiveSheet.Cells[1, 0].CellPadding = new CellPadding(5);

 

Step 4:DiagonalCellType设计方法

在双区域、三区域、四区域这3种对角线,彼此之间可复用的代码非常多,故我们考虑了采用如下设计模式:工厂方法、模板方法、策略方法、桥接模式等。

为了简化设计,对DiagonalCellType做了抽象,仅用了24行代码实现了一个对角线的接口类。

  1:     public class DiagonalCellType : FarPoint.Win.Spread.CellType.TextCellType
  2:     {
  3:         #region CTOR
  4:         SubDiagonalCellTypeBase m_cellType = null;
  5:         public DiagonalCellType(DiagonalSubCellType subType)
  6:         {
  7:             m_cellType = SubDiagonalCellTypeBase.CreateSubType(subType);
  8:         }
  9:         #endregion
 10:
 11:         public void SetText(string text, StringAlignment sstringAlignment = StringAlignment.Near, StringFormatFlags ssStringFormatFlags = StringFormatFlags.NoClip)
 12:         {
 13:             m_cellType.SetText(text, sstringAlignment, ssStringFormatFlags);
 14:         }
 15:
 16:         public override void PaintCell(Graphics g, Rectangle r, Appearance appearance, object value, bool isSelected, bool isLocked, float zoomFactor)
 17:         {
 18:             m_cellType.PaintCell(g, r, appearance, value, isSelected, isLocked, zoomFactor);
 19:         }
 20:
 21:         public override System.Windows.Forms.Control GetEditorControl(System.Windows.Forms.Control parent, Appearance appearance, float zoomFactor)
 22:         {
 23:             return null;
 24:         }
 25:     }

 

DiagonalCellType继承自TextCellType,为了复用已有的文本单元格属性,而不是“从轮子做起”。这里,我们重载了2个函数,并作了函数覆盖:

PaintCell:GDI+绘制文本、线条核心函数,具体实现3种区域对角线不一样,故在SubDiagonalCellTypeBase类中延迟实现之。

GetEditorControl:考虑到表头区域在绘制表格前已经确定,不需要编辑,故重写函数,返回null则屏蔽了默认的Editor控件。

Step 5: 双区域对角线编码实践

SubDiagonalCellType_2Region是双区域对角线的实现类,共36行代码:

  1:     public class SubDiagonalCellType_2Region : SubDiagonalCellTypeBase
  2:     {
  3:         public override void InnerPaintCell(Graphics g, Rectangle r, Appearance appearance, object value, bool isSelected, bool isLocked, float zoomFactor)
  4:         {
  5:             //line 1
  6:             g.DrawLine(LinePen, r.X, r.Y, r.X + r.Width, r.Y + r.Height);
  7:
  8:             //text 1
  9:             SizeF sf = m_TextList[0].GetSizeF(g, appearance);
 10:             float x = r.X + r.Width/2 - sf.Width - appearance.CellPadding.Left;
 11:             float y = r.Y + appearance.CellPadding.Top;
 12:             RectangleF rr = new RectangleF(x, y, r.Right - x - appearance.CellPadding.Left, sf.Height);
 13:            // g.FillRectangle(new SolidBrush(Color.White), rr); //Test Rectangle Size
 14:             m_TextList[0].DrawString(g, rr, appearance);
 15:
 16:             //text 2
 17:             sf = m_TextList[1].GetSizeF(g, appearance);
 18:             y = r.Y + r.Height - sf.Height - appearance.CellPadding.Bottom;
 19:             x = r.X + appearance.CellPadding.Left;
 20:             rr = new RectangleF(x, y, r.Width / 2 , sf.Height);
 21:            // g.FillRectangle(new SolidBrush(Color.White), rr); //Test Rectangle Size
 22:             m_TextList[1].DrawString(g, rr, appearance);
 23:         }
 24:
 25:         protected override void ValidateData()
 26:         {
 27:             if (m_TextList.Count != 2)
 28:             {
 29:                 throw new Exception("must SetText twice");
 30:             }
 31:         }
 32:
 33:         public override DiagonalSubCellType DiagonalSubCellType
 34:         {
 35:             get { return DiagonalSubCellType.e2Region; }
 36:         }
 37:     }

 

  • DiagonalSubCellType: 用来标明当前类属于哪种类型

  • ValidateData:数据校验,因为双区域需要2个文本,故做判断处理,不满足条件抛出异常。

  • InnerPaintCell:实现绘制双区域的函数,这里采用的模板方法,在基类SubDiagonalCellTypeBase已经实现了ValidateData-数据校验、背景色填充等。

  • 前景色、背景色、bore、CellPadding复用了Cell自带的,亦可通过Designer设计。

  • 为了方便用户使用,添加了编辑器修改对角线文字(文字行不可增减)

Spread_Diaonal

GDI+的一些注意事项:

  • 垃圾回收完毕后,销毁GDI+对象,这里我们通过微软推荐的using。

  • 在使用的Form中,启用buffer和双缓存,代码如下:

  1: //提高GDI+ 效率
  2: this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
  3:

 

代码如下:

Spread_DiagonalCellType_demo.zip


© 著作权归作者所有

文刚的技术博客
粉丝 94
博文 19
码字总数 23458
作品 0
西安
技术主管
私信 提问
SpreadJS纯前端表格控件V11.1震撼来袭

全球最大的控件提供商葡萄城宣布,纯前端表格控件SpreadJS 正式发布2018 V11.1 版本,新版本提供撤销/重做功能,并增强了UI和数据筛选,极大的扩展了产品的实用功能,可更加方便优雅的嵌入您...

powertoolsteam
2018/06/26
0
0
利用FarPoint Spread表格控件,构造Winform的Excel表格界面输入

因有一个业务需要在Winform界面中,以类似Excel表格界面中录入相关的数据(毕竟很多时候,客户想利用成熟的软件体验来输入他们想要的东西),其中界面需要录入基础信息,列表信息,图片信息等...

walb呀
2017/12/04
0
0
介绍一款开源的类Excel电子表格软件

Excel一直以霸主的地位,占据了Windows桌面表格软件市场No 1,与此同时,Office套装产品几乎成为了IT行业的标配办公技能。有无类似Excel的桌面程序,绿色版,实现基本的数据编辑功能呢? 假如...

葡萄城技术团队
2014/10/09
5.2K
6
JQuery Datatables Columns API 参数详细说明

Data Tables: http://datatables.net/ Version: 1.10.0 Columns说明 虽然我们可以通过DOM直接获取DataTables元素的信息,但是DataTables提供了更方便的方法,可以自定义列的属性。下边就让我...

银月光海
2016/06/12
1K
0
Datatables_API 参数详细说明

Data Tables: http://datatables.net/ Version: 1.10.0 Columns说明 虽然我们可以通过DOM直接获取DataTables元素的信息,但是DataTables提供了更方便的方法,可以自定义列的属性。下边就让我...

喵王不瞌睡
2015/05/02
13.9K
0

没有更多内容

加载失败,请刷新页面

加载更多

3_数组

3_数组

行者终成事
今天
7
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0
OpenJDK之CyclicBarrier

OpenJDK8,本人看的是openJDK。以前就看过,只是经常忘记,所以记录下 图1 CyclicBarrier是Doug Lea在JDK1.5中引入的,作用就不详细描述了,主要有如下俩个方法使用: await()方法,如果当前线...

克虏伯
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部