DataGridView实现添加合计行并始终显示在底部

本文介绍了一种在DataGridView中实现合计行始终可见的技术方案。通过分别设置数据区和合计区的DataGridView,并借助额外的滚动条控制,使得合计行在水平和垂直滚动时保持固定位置。此外,还提供了自动计算合计行数值的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DataGridView中没有合适的方法来冻结底部的合计行,这里用一种比较简单的方式实现。
1.数据部分的DataGridView,不带任何滚动框
2.合计部分的DataGridView,带有横向滚动框
3.在画面上添加一个纵向滚动框
实现的主要思路就是用合计行的横向滚动框控制两个DataGridView的横向滚动,右侧的纵向滚动狂控制数据部分的DataGridView,效果看起来就是合计行始终显示。

该例实现了合计行的自动计算,取数据的部分是用程序做的DataTable

DataGridViewSumRow类
PublicClassDataGridViewSumRow

PrivatedtAsDataTable
DimdtSumAsDataTable
PrivateROW_HEIGHTAsInteger=21''行高

PrivateSubDataGridViewSumRow_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesMyBase.Load
VScrollBar1.Visible
=False
EndSub


PrivateSubButton1_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesButton1.Click

dt
=GetData()
Me.DataGridView1.DataSource=dt
Me.DataGridView1.RowTemplate.Height=ROW_HEIGHT

GetSumData()

''行数超过当前页显示时显示纵向滚动条
Ifdt.Rows.Count>13Then

VScrollBar1.Visible
=True
''总长度为(所有行数-画面一页显示行数)×行高
VScrollBar1.Maximum=(Me.DataGridView1.Rows.Count-Me.DataGridView1.DisplayedRowCount(False))*ROW_HEIGHT
VScrollBar1.Minimum
=0
VScrollBar1.SmallChange
=21
VScrollBar1.LargeChange
=50

EndIf

EndSub



'''<summary>
'''合计取得设定
'''</summary>
'''<remarks></remarks>

PrivateSubGetSumData()
DimdrAsDataRow

dtSum
=NewDataTable("TEST")

dtSum
=dt.Clone

DimrdmAsRandom=NewRandom
dr
=dtSum.NewRow()
dr(
0)="合计"

ForiAsInteger=1Todt.Columns.Count-1
dr(i)
=dt.Compute("Sum("+dt.Columns(i).ColumnName+")","true")
Next
dtSum.Rows.Add(dr)

Me.DataGridViewSum.DataSource=dtSum
Me.DataGridViewSum.Rows(0).DefaultCellStyle.BackColor=Color.Brown
Me.DataGridViewSum.ReadOnly=True
Me.DataGridViewSum.SelectionMode=DataGridViewSelectionMode.FullRowSelect

EndSub


'''<summary>
'''数据取得
'''</summary>
'''<returns></returns>
'''<remarks></remarks>

PublicFunctionGetData()AsDataTable

DimdtAsDataTable
DimdrAsDataRow

dt
=NewDataTable("TEST")
dt.Columns.Add(
NewDataColumn("号码",GetType(String)))
dt.Columns.Add(
NewDataColumn("数量1",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量2",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量3",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量4",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量5",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量6",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量7",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量8",GetType(Integer)))
dt.Columns.Add(
NewDataColumn("数量9",GetType(Integer)))

DimrdmAsRandom=NewRandom

ForiAsInteger=10To80
dr
=dt.NewRow()
dr(
0)="00"&i.ToString
ForjAsInteger=1To9
dr(j)
=rdm.Next(1000,5000)
Next
dt.Rows.Add(dr)
Next

Returndt
EndFunction


'''<summary>
'''纵滚动条事件
'''</summary>
'''<paramname="sender"></param>
'''<paramname="e"></param>
'''<remarks></remarks>
PrivateSubVScrollBar1_Scroll(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.ScrollEventArgs)HandlesVScrollBar1.Scroll
'Debug.WriteLine(e.NewValue.ToString)
Me.DataGridView1.FirstDisplayedScrollingRowIndex=e.NewValueROW_HEIGHT

EndSub


PrivateSubButton2_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesButton2.Click
Me.Close()
EndSub



'''<summary>
'''合计DataGridView的滚动条事件
'''</summary>
'''<paramname="sender"></param>
'''<paramname="e"></param>
'''<remarks></remarks>

PrivateSubDataGridViewSum_Scroll(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.ScrollEventArgs)HandlesDataGridViewSum.Scroll
Me.DataGridView1.HorizontalScrollingOffset=e.NewValue
EndSub


'''<summary>
'''数据变更后重新合计
'''</summary>
'''<paramname="sender"></param>
'''<paramname="e"></param>
'''<remarks></remarks>
PrivateSubDataGridView1_CellValueChanged(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.DataGridViewCellEventArgs)HandlesDataGridView1.CellValueChanged
Ife.ColumnIndex<=0Then
ExitSub
EndIf
''DetaGridView中数据变化后重新合计
Me.DataGridViewSum(e.ColumnIndex,0).Value=dt.Compute("Sum("+dt.Columns(e.ColumnIndex).ColumnName+")","true")
EndSub



'''<summary>
'''响应鼠标滚轴事件
'''</summary>
'''<paramname="sender"></param>
'''<paramname="e"></param>
'''<remarks></remarks>
PrivateSubDataGridViewSumRow_MouseWheel(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.MouseEventArgs)HandlesMe.MouseWheel

IfVScrollBar1.Visible=FalseThen
ExitSub
EndIf

IfVScrollBar1.Value-ROW_HEIGHT<0Ande.Delta>0Then
VScrollBar1.Value
=VScrollBar1.Minimum
ExitSub
EndIf

IfVScrollBar1.Value+ROW_HEIGHT>VScrollBar1.MaximumAnde.Delta<0Then
VScrollBar1.Value
=VScrollBar1.Maximum
ExitSub
EndIf

Try
VScrollBar1.Value
-=CInt(e.Delta/Math.Abs(e.Delta)*ROW_HEIGHT)
CatchexAsException
Debug.WriteLine(
"###########################")
Debug.WriteLine(
"VScrollBar1.Value="&VScrollBar1.Value)
Debug.WriteLine(
"e.Delta="&e.Delta)
Debug.WriteLine(
"###########################")
EndTry
Me.DataGridView1.FirstDisplayedScrollingRowIndex=VScrollBar1.ValueROW_HEIGHT

EndSub

EndClass

效果如下
*调整导出及打印的格式与显示一致;合计,详细参见第10条修正功能,全部源码及示例。 * 文 件 名:DataGridViewEx.cs * 创 建 人:明振居士 * Email:nzj.163@163.com qq:342155124 * 创建时间:2010-06-01 * 最后修改时间: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事件 * 增加了导出和打印对应的支持,所见即所得的对齐方应用于式导出及打印。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值