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

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM