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

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

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

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

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

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

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

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

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

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

Step 1: 输入文字需求

  • 字体默认获取系统的
  • 斜线的颜色和宽度可自定义
  • 背景色和前景色可自定义
  • 可选择文字对齐方向,并对超出区域文字剪裁处理
  • 编辑CellType区域
  • Step 2:依据文字需求,快速手绘原型:

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

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

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设计。
    为了方便用户使用,添加了编辑器修改对角线文字(文字行不可增减)

GDI+的一些注意事项:

  • 垃圾回收完毕后,销毁GDI+对象,这里我们通过微软推荐的using。
  • 在使用的Form中,启用buffer和双缓存,代码如下:
  1: //提高GDI+ 效率
  2: this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
  3: 

代码如下:

Spread 之自定义对角线cellType源码: DiagonalCellType的更多相关文章

  1. C#/ASP.NET MVC微信公众号接口开发之从零开发(四) 微信自定义菜单(附源码)

    C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...

  2. WPF一步步实现完全无边框自定义Window(附源码)

    在我们设计一个软件的时候,有很多时候我们需要按照美工的设计来重新设计整个版面,这当然包括主窗体,因为WPF为我们提供了强大的模板的特性,这就为我们自定义各种空间提供了可能性,这篇博客主要用来介绍如何自 ...

  3. nGrinder对监控机器收集自定义数据及源码分析

    转载:https://blog.csdn.net/neven7/article/details/50782451 0.背景 性能测试工具nGrinder支持在无需修改源码的情况下,对目标服务器收集自定 ...

  4. Android 自定义相机Demo源码

    Github源码:https://github.com/LinJZong/AndroidProject.git 模仿360相机,图片资源来源于360相机,仅供学习使用.使用过程中遇到问题或Bug可发我 ...

  5. 【转】ANDROID自定义视图——onLayout源码 流程 思路详解

    转载(http://blog.csdn.net/a396901990) 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量——onMeasure():决定View的大小 2.布局 ...

  6. iOS分段选择器、旅行App、标度尺、对对碰小游戏、自定义相册等源码

    iOS精选源码 企业级开源项目,模仿艺龙旅行App 标签选择器--LeeTagView CSSegmentedControl常用的分段选择器,简单易用! 仿微信左滑删除 IOS左滑返回 输入框 iOS ...

  7. 6.2 dubbo在spring中自定义xml标签源码解析

    在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ...

  8. HTML5视频(自定义视频播放器源码)

    video对象 兼容情况: safari浏览器不支持webm格式 Chrome浏览器支持webm格式 ie8以及以下不支持video标签 , ie9支持video标签 ,但是支持mp4格式的 Fire ...

  9. 【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

    原文地址:http://blog.csdn.net/a396901990/article/details/36475213 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量—— ...

随机推荐

  1. ST-Link 驱动安装

    电脑中可以预先安装一个ST Visual Programmer 这个直接带STLink驱动或是安装一个STM32 ST-Link Uitilty 然后选择自安安装 点出下一步 在弹出的对话框选择“仍然 ...

  2. D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建

    说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...

  3. Activity详解

    Activity是android应用的重要组成单元之一(另外3个是Service,BroadcastReceiver和ContentProvider).实际应用包含了多个Activity,不同的Act ...

  4. ajax 返回json数据操作

    例子: $.ajax({ url: "<?=Url::toRoute('add-all-staff')?>", type: 'get', dataType: 'json ...

  5. Linux基本操作 9----- 认识与学习bash

    一 认识bash这个shell 1 管理整个计算机硬件的其实就是操作系统的内核,这个内核是需要被保护的,所以我们一般用户就只能通过shell来跟内核通信,以让内核达到我们所想打到的工作. 2 只要能够 ...

  6. Ognl表达式语言

    l  OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的表达式语言. ...

  7. hadoop安装与WordCount例子

    1.JDK安装 下载网址: http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u29-download-513648.html  ...

  8. UITableview 中获取非选中的cell

    实现效果如图: 在cell中有一个button,选中cell改变button的选择状态 yes,选中另外一个cell,别的cell中的button选择状态变成false. //获取当前可显示的cell ...

  9. Java基础知识强化之IO流笔记71:NIO之 NIO的(New IO流)介绍

    1. I/O 简介 I/O ( 输入/输出  ):指的是计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键,因而所有 I/O 的主体实际上是内置在操作系统中的. ...

  10. 0x80029C4A

    法将类型为“Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Exc ...