Winform DataGridView扩展系列(一)

写一个win form的程序,要用到DataGridView的汇总行,网上找了找,不是要钱就是有点小问题。想了想,自己写一个吧,看看以前打下的底子还中不,呵呵。

要写就的有构想,前前后后想了几天把我要的罗列了一下:汇总行、多列表头(中国报表)、百分比列、计算器列、时间列、日期列。几个DataGridVewColumn的继承扩展没啥难度,就前两个要费点力。开工,干了。

先看看结果:

a)汇总行(继承DataGridView控件实现)

b)多列表头(组件方式的实现)

一、汇总行(继承DataGridView控件)实现:

  1. 要求: 

    a.不影响DataGridView本身的运行,并尽量保持与DataGridView的整体外观一致

    b.减少闪烁。

    c.提供较完整的设计时支持。

    2.实现:

    a.类层次结构

      

 1  ///   <summary>     
 2   
 3         ///  有底部分析区域的DataGridView控件类,继承自DataGridView    
 4   
 5         ///   </summary>     
 6   
 7        public  class FootDataGridView : DataGridView{}
 8  
 9         ///   <summary>
10   
11         ///  Panel控件扩展类,应用于FootDataGridView    
12   
13         ///   </summary>     
14   
15        public  class FootBand : Panel
16  
17       {
18  
19          #region 附属类
20  
21         [DefaultProperty( " ColumnName ")]        
22  
23          public  class FootItem{}
24  
25         [Editor( typeof(ZYQ.Design.Utilities.Editor.DataGridViewFootCollectionEditor), typeof(UITypeEditor))]        
26  
27          public  class FootItemCollection : List<FootItem>{}
28  
29          #endregion
30  
31       }

 

    b.设计时支持

     c.细节与实现:

      属性和方法等的实现没啥好说的,MSDN中都有。难度在呈现UI上。

      为减少闪烁,必须声明开启双缓存。

       

private  void Initialize()        
 
      {            
 
         #region 声明使用双缓存            
 
        SetStyle(ControlStyles.DoubleBuffer |
 
                                     ControlStyles.OptimizedDoubleBuffer |
 
                                     ControlStyles.AllPaintingInWmPaint,
 
                                      true);
 
                UpdateStyles();
 
                 #endregion
 
        ......
 
      }

 

      为配合DataGridView的动作使汇总行跟随改变,必须重写一些事件引发的函数来重新计算汇总行绘制所需要的数据,他们是:

      

protected  override  void OnPaint(PaintEventArgs e),
 
       protected  override  void OnCellValueChanged(DataGridViewCellEventArgs e)
 
       protected  override  void OnColumnWidthChanged(DataGridViewColumnEventArgs e)
 
       protected  override  void OnColumnDividerWidthChanged(DataGridViewColumnEventArgs e)
 
       protected  override  void OnGridColorChanged(EventArgs e)
 
       protected  override  void OnResize(EventArgs e)
 
       protected  override  void OnRowHeadersWidthChanged(EventArgs e)
 
       protected  override  void OnSizeChanged(EventArgs e)
 
       protected  override  void OnVisibleChanged(EventArgs e)
 
       protected  override  void OnScroll(ScrollEventArgs e)
 
       protected  override  void OnColumnRemoved(DataGridViewColumnEventArgs e)
 
       protected  override  void OnBackgroundColorChanged(EventArgs e)
 
       protected  override  void OnRowHeadersDefaultCellStyleChanged(EventArgs e)
 
       protected  override  void OnColumnStateChanged(DataGridViewColumnStateChangedEventArgs e)

 

      汇总行的绘制必须是在DataGridView创建后才开始的,所以必须获得DataGridView的HandleCreated事件的通知;而要绘制汇总行必须使用Panel的Paint事件.

      

  private  void Initialize()        
 
      {
 
        ......
 
         base.HandleCreated +=  new EventHandler(FootDataGridView_HandleCreated);
 
        _foot.Paint +=  new PaintEventHandler(_foot_Paint);
 
        ......
 
      }
 
       void FootDataGridView_HandleCreated( object sender, EventArgs e)
 
            {            
 
        _foot.ParentIsCreated =  this.Created;
 
           }
 
       void _foot_Paint( object sender, PaintEventArgs e)
 
             {                           
 
        // 画分割线
 
              if (ShowDividedLine)
 
             {
 
           OnPaintDividedLine(e.Graphics);
 
              }
 
               // 画foot header
 
               if (RowHeadersVisible)
 
                {
 
                OnPaintFootHeader(e.Graphics);
 
                }
 
                   // 画底部区域
 
                  OnPaintColumnsFoot(e);
 
      }

 

      所有重写的事件引发函数调用RaisePanel()函数来引发Panel的Paint事件

      

             private  void RaisePanel()
 
            {
 
         if (_foot.Visible)
 
                {
 
                      if (Created)
 
                     {
 
                           ResetButtomPanel();
 
                           PaintEventArgs parg =  new PaintEventArgs(_foot.CreateGraphics(), _foot.ClientRectangle);
 
                           ClearFoot(parg.Graphics);
 
                           _foot_Paint(_foot, parg);
 
                     }
 
                }
 
           }

 

     绘制过程用GDI+,没什么特别的,只要搞清楚剪辑使用的就行了。

使用下来感觉很好,和DataGridView配合很好,没有闪烁的情况。后续开发的时候可以利用Panel的特性加入鼠标、绑定、重算等功能。

 

转载请注明:http://www.cnblogs.com/RZYQ/archive/2011/12/28/2305257.html

  

转载于:https://www.cnblogs.com/RZYQ/archive/2011/12/28/2303772.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
开发环境为vs2012 C#源码及完全样例 此版本为2012.2.24日更新版本,更新内容为 * 最后修改时间:2012.2.24 增加了汇总信息的自定义控制属性,参见功能描述12 * 2012.2.23 修改了过多列时父标题不显示的问题,重新写了算法,修改了标题头重叠及不能换行的问题,参见说明11. 总功能列举如下: /**************************************************************************************************** * Copyright (C) 2012 明振居士 版权没有,任意拷贝及使用,但对使用造成的任何后果不负任何责任,互相开源影响,共同进步 * 文 件 名:DataGridViewEx.cs * 创 建 人:明振居士 * Email:nzj.163@163.com qq:342155124 * 创建时间:2010-06-01 * 最后修改时间:2012.2.24 增加了汇总信息的自定义控制属性,参见功能描述12 * 2012.2.23 修改了过多列时父标题不显示的问题,重新写了算法,修改了标题头重叠及不能换行的问题,参见说明11. * 2012-1-19 增加第10条所示的功能;修改了列头超过26列的错误,导出excel为数组方式,速度更快,导出的单元格设置为文本格式。 * 标 题:用户自定义的DataGridView控件 * 功能描述:扩展DataGridView控件功能 * 扩展功能: * 1、搜索Search(); 有两个同明方法,参数不同 F3为快捷键继续向下搜索 * 2、用TreeView HeadSource 来设置复杂的标题样式,如果某个节点对应的显示列隐藏,请将该节点Tag设置为hide,隐藏列的排列位置与绑定数据元列位置对应,树叶节点的顺序需要与结果集的列顺序一致 * 3、通过反射导出Excel,无需引用com组件,方法ExportExcel() ,不受列数的限制,表头同样可以导出,AutoFit属性设置导出excel后是否自动调整单元格宽度 * 导出内容支持自定义的:Title List Header List Footer,支持在设计时值的设定,窗口关闭时Excel资源自动彻底释放 * 4、可以自己任意设定那些列显示及不显示,通过调用方法SetColumnVisible()实现。 * 5、设置列标题SetHeader(),设置列永远可见AlwaysShowCols(),设置列暂时不可见HideCols() * 注意,当使用了TreeView作为复杂Header时,不要使用本方法,Header显示的内容根据treeview内容而显示 * 6、列宽度及顺序的保存SaveGridView(),加载LoadGridView() * 7、支持所见即所得的打印功能,举例如下 * private void button5_Click(object sender, EventArgs e) { DGVPrinter printer = new DGVPrinter(); printer.PrintPreviewDataGridView(DataGridViewEx1); } * 8、自定义合并行与列,行合并用 MergeRowColumn 属性,列合并用MergeColumnNames属性,都可以定义多个列 * 9、行标号的设置 bool ShowRowNumber; * 10、增加最后一行的汇总行,支持列的聚合函数,参见http://msdn.microsoft.com/zh-cn/library/system.data.datacolumn.[removed]v=VS.100).aspx * 假设对id列显示“合计”字符,avgPrice进行平均值,total列显示合计,则对ComputeColumns属性增加三行内容:id,合计:;avgPrice,Avg(avgPrice);total,Sum(total) * 如果需要对值进行格式控制,请实现beforeShow事件 * 增加了导出和打印对应的支持,所见即所得的对齐方应用于式导出及打印。 * 11、列标题头自动换行,默认设置为每个列标题头行高为22,如果设置的字体更大,将自动进行计算。如果需要多行显示,请根据需要调节ColumnHeaderHeight属性值, * 其估算方法为预计的标题头层数乘以22,或层数乘以设置的字体高度。 * 12、针对第10条功能,增加汇总信息的自定义控制属性,汇总字体SummaryFont,汇总字体颜色SummaryFontColor,汇总背景色SummaryBGColor,边框与整个表格边框一致 ****************************************************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值