[转载]C# DataGridView合计行完整解决方法

[转载]C# DataGridView合计行完整解决方法、用户体验深刻、超实用 – 专注实用,代码真实可用 – 博客园.

在网络上看过很多关于DataGridView合计的设计及源码,搜到了很多相同的文章(都是相互复制),一点创新都没有。

普遍存在的问题是用户体现不行,或存在很多BUG等。。

很多的人写的解决办法如下几条:

  1. DataGridView的最后一行作为合计行,每增加或删除一行后重新计算合计行。
  2. 用两个大小相同的DataGridView,一个是数据表格,一个是合计表格。
  3. 第三个是用Table类SUM增加一条合计行数据,再显示到DataGridView中。
  4. 干脆用第三方控件。。。。。。。。

以上出现的问题:

合计行不能显示在DataGridView界面的最下方,用户只能滚条到表格最后才能看到合计。

如果用两个DataGridView,那我只能说他是“天才”,我想性能怎么样,大家可想而知。

如果用Table类SUM一条,同样会产生只能要最后一行看到,如果别人不使用Table显示到DataGridView中怎么办。

上述的都不能很好的解决DataGridView合计行,以下是我个人设计原理与说明:

首先我们解决的是不管用什么方式填充DataGridView数据都能够合计数据。

必须显示在DataGridView界面的最下方,这样用户体验深刻一点。

从上我们可以看到,我们要做到合计行的话,我们必须在表现层(UI)做,不要在逻辑层与数据层做,(如果出错的话只是显示错误)

最终效果如下:

合计我使用的是Lable对象。DataGridView需要处理的事件有单元格的数据改变事件CellValueChanged,滚动条事件,列宽事件,这件事件发生后重绘Lable及计算所需要列数据。

定义对象:Lable对象名为FootSumLabel,DataGridView对象名为DetailDataGrid

代码

//定义类的私有变量,两个是滚动条 HScrollBar hs; VScrollBar vs; //合计数值 decimal fSumQty = 0, fSumCBAmount = 0; //加载数据时先注册DetailDataGrid的滚动条事件,在类的构造时注册
 //DetailDataGrid类中包括有HScrollBar,VScrollBar如下 //hs_ValueChanged,vs_ValueChanged两个事件都重绘FootSumLabel,即FootSumLabel.Invalidate();这一句语句 hs = ((HScrollBar)this.DetailDataGrid.Controls[0]); vs = ((VScrollBar)this.DetailDataGrid.Controls[1]); hs.ValueChanged += new EventHandler(hs_ValueChanged); vs.ValueChanged += new EventHandler(vs_ValueChanged); //DetailDataGrid的CellValueChanged事件调用sumdata(); //FootSumLabel的重绘Paint事件 private void FootSumLabel_Paint(object sender, PaintEventArgs e) { int count = DetailDataGrid.Columns.Count; DataGridViewColumnCollection Columns = this.DetailDataGrid.Columns; Graphics grf = e.Graphics; int x = this.DetailDataGrid.RowHeadersWidth - 2; StringFormat strfmt = new StringFormat(); strfmt.Alignment = StringAlignment.Far; for (int i = 0; i < count; i++) { x += Columns[i].Width; if (i == 4) { int xx = x + Columns[i + 1].Width; grf.DrawString(string.Format("{0:F2}", fSumQty), this.FootSumLabel.Font, Brushes.Black, xx - hs.Value, 3, strfmt); } if (i == 7) { int xx = x + Columns[i + 1].Width; grf.DrawString(string.Format("{0:F2}", fSumCBAmount), this.FootSumLabel.Font, Brushes.Black, xx - hs.Value, 3, strfmt); } } } //合计数值函数 private void sumdata() { fSumQty = 0; fSumCBAmount = 0; DataGridViewRowCollection rows = this.DetailDataGrid.Rows; foreach (DataGridViewRow row in rows) { fSumQty += Convert.ToDecimal(row.Cells["fQty"].Value); fSumCBAmount += Convert.ToDecimal(row.Cells["fAmount"].Value); } //重画 this.FootSumLabel.Invalidate(); }

以上代码可以自行加工成一个类,DataGridView调整列宽的事件只要调用重绘FootSumLabel就可以了。如果有不正之处请指出。

如果要转帖请注明出处:http://www.cnblogs.com/NetWZ/articles/1862097.html 作者:.NetWZ

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏