热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> .Net编程>>正文内容

在DataGridView底部实现统计行【附实例代码】

发布时间:2010年01月15日点击数: 朱祁林

【示例代码下载】

在开发一个基于Window Form的CS应用程序的时候,我搜索过一个这样的DataGridView 控件,它能显示一列内容的总和。例如:统计顾客订单的总数,显示在Grid中的一列上。就像Excel能做的一样,我没有找到一个合适的解决方案,所以我决定自己开发一个组件。它能像DataGridView一样工作,能在表格的底部显示一行。

为了SummaryRow的重新定位和大小的调整,我重构了一些代码,代码借用了Robert Rhode写的Nice Filterable DataGrid。

为了能运行SummaryDataGridViewTest-Application ,必要将Nwind.mdb 数据库拷贝到输出路径下面。

非常好的DataGridView和Window-Forms类库的知识有助于你定制代码,但是它不是必要的。因为使用SummaryDataGridView 非常的简单。

SummaryDataGridView 能像任何其他Windows-Forms 控件一样使用。支持设计时的设定。在设计上,它有一组公共属性。使用类似DataGridView ,因为它是继承了DataGridView。为了显示数据,需要设置控件的DataSource 属性。每一列必须添加到字符串数组SummaryColumns中。看图1和图2的公有属性,看他们是如何影响SummaryDataGridView的。

 

 

SummaryRow

使用DataGridView 的一行作为总结行是一件非常棘手的事情,会带来很多问题。我没有找到在表格的底部固定SummaryRow的解决方案,它又必须是滚动的。由于这个原因,我使用一个带Textboxe的简单控件,它显示在DataGridView的下面。所有的textbox和DataGridView一起改变自己的大小。此外它必须利用自己的水平滚动条将显示在我们的SummaryControlContainer下面,而不是使用显示在SummaryRow上面的DataGridView的水平滚动条。因此有相当一部分的代码是处理SummaryRow的定位、大小、排序的。总结一行的值是控件中最容易实现的部分。下面的DataGridView事件的处理是为了使DataGridView和SummaryRow同步:

ColumnAdded, ColumnRemoved, ColumnStateChanged, ColumnDisplayIndexChanged

为了了解更多的关于同步的信息,看这些方法:SummaryControlContainer 类的reCreateSumBoxes() 和resizeSumBoxes() 方法

SummaryRow 和DataGridView粘合:

如何将SummaryRow 附加到DataGridView上面。最简单的方式是使用一个控件将SummaryRow 和DataGridView包含在其中。通过一个公共属性在表格之间访问。我决定让DataGridView创建自己的SummaryRow。为了避免设计时出现的问题,我们在运行时完成。在DataGridView 初始化之后,调用 ChangeParent() 方法。这个方法从父控件移除DataGridView ,在这个地方创建一个panel,然后在这个panel中包含DataGridView 和SummaryRow 。在移除DataGridView之前,我们必须在TableLayoutPanel上确定确切位置。

  1. private void changeParent() 
  2.       { 
  3.           if (!DesignMode && Parent != null
  4.          { 
  5.  
  6.             [..] 
  7.               panel.Bounds = this.Bounds; 
  8.               panel.BackColor = this.BackgroundColor;                                      
  9.               panel.Dock = this.Dock; 
  10.               [..] 
  11.  
  12.               summaryControl.Dock = DockStyle.Bottom; 
  13.               this.Dock = DockStyle.Fill;                 
  14.  
  15.    
  16.   Special handling for TableLayoutPanels 
  17.            if (this.Parent is TableLayoutPanel) 
  18.            { 
  19.                int rowSpan, colSpan; 
  20.  
  21.                TableLayoutPanel tlp = this.Parent as TableLayoutPanel;                    
  22.                TableLayoutPanelCellPosition cellPos =  
  23.                tlp.GetCellPosition(this); 
  24.  
  25.                rowSpan = tlp.GetRowSpan(this); 
  26.                colSpan = tlp.GetColumnSpan(this); 
  27.  
  28.                tlp.Controls.Remove(this); 
  29.                tlp.Controls.Add(panel, cellPos.Column, cellPos.Row); 
  30.                tlp.SetRowSpan(panel, rowSpan); 
  31.                tlp.SetColumnSpan(panel, colSpan); 
  32.  
  33.              } 
  34.              else 
  35.              { 
  36.                  Control parent = this.Parent; 
  37.  
  38.                  remove DataGridView from ParentControls 
  39.                  parent.Controls.Remove(this); 
  40.                  parent.Controls.Add(panel);                     
  41.              } 
  42.  
  43.              summaryControl.Controls.Add(hScrollBar); 
  44.              hScrollBar.BringToFront(); 
  45.              panel.Controls.Add(this); 
  46.              panel.Controls.Add(summaryControl); 
  47.  
  48.              adjustSumControlToGrid(); 
  49.              adjustScrollbarToSummaryControl(); 
  50.              resizeHScrollBar();                 
  51.          } 
  52.      } 

只读的TextBox:

一个标准的Windows窗体TextBox,使其ReadOnly属性设置为true 主要问题是,认为该文本框颜色更改为Caption(灰),不能设置其他的颜色。我想让SummaryRow 的背景颜色是纯白色。这就是为什么我要包括我自己的TextBox。这是一个简单的控件,因为在TextBox中没有EventHandling。TextBox能获得IsSummary属性来表明是否用来合总。直接在OnPaint事件中绘制控件。

  1. protected override void OnPaint(PaintEventArgs e) 
  2.   {          
  3.       Rectangle textBounds; 
  4.       textBounds = new Rectangle(this.ClientRectangle.X + 2, this.ClientRectangle.Y + 2, 
  5.           this.ClientRectangle.Width - 2, this.ClientRectangle.Height - 2); 
  6.       using (Pen pen = new Pen(borderColor)) 
  7.       { 
  8.          e.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle); 
  9.          e.Graphics.DrawRectangle(pen, this.ClientRectangle.X, this.ClientRectangle.Y, 
  10.              this.ClientRectangle.Width - subWidth, this.ClientRectangle.Height - 1); 
  11.          e.Graphics.DrawString(Text, Font, Brushes.Black, textBounds, format); 
  12.        } 
  13.   } 

在公共属性SumaryRowBackColor中设置SummaryRow的颜色

实际是在calcSummaries()方法中统计列值,这个方法在 DataGridView的 [RowsAdded] [RowsRemoved] 和[CellValueChanged] 事件处理中调用。 它通过遍历DataGridView 的每一行在SummaryColumn上总计列值。

本站热点业务

更多模板/案例展示

关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作