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

本文介绍了如何在DataGridView中创建一个始终显示在底部的合计行。通过使用两个独立的DataGridView和一个纵向滚动条,实现了当数据行滚动时,合计行保持可见。同时,实现了合计行的自动计算功能,并提供了详细的代码示例。

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

 DataGridView中没有合适的方法来冻结底部的合计行,这里用一种比较简单的方式实现。

1. 数据部分的DataGridView,不带任何滚动框

2.合计部分的DataGridView,带有横向滚动框

3.在画面上添加一个纵向滚动框

实现的主要思路就是用合计行的横向滚动框控制两个DataGridView的横向滚动,右侧的纵向滚动狂控制数据部分的DataGridView,效果看起来就是合计行始终显示。

 

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

 

DataGridViewSumRow

Public Class DataGridViewSumRowClass DataGridViewSumRow

 

    Private dt As DataTable

    Dim dtSum As DataTable

    Private ROW_HEIGHT As Integer = 21 ''行高

 

Private Sub DataGridViewSumRow_Load()

Sub DataGridViewSumRow_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        VScrollBar1.Visible = False

    End Sub

 

    Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

 

        dt = GetData()

        Me.DataGridView1.DataSource = dt

        Me.DataGridView1.RowTemplate.Height = ROW_HEIGHT

 

        GetSumData()

 

        ''行数超过当前页显示时显示纵向滚动条

        If dt.Rows.Count > 13 Then

 

            VScrollBar1.Visible = True

            ''总长度为 (所有行数 - 画面一页显示行数) × 行高

            VScrollBar1.Maximum = (Me.DataGridView1.Rows.Count - Me.DataGridView1.DisplayedRowCount(False)) * ROW_HEIGHT

            VScrollBar1.Minimum = 0

            VScrollBar1.SmallChange = 21

            VScrollBar1.LargeChange = 50

 

        End If

 

    End Sub

 

 

    ''' <summary>

    ''' 合计取得设定

    ''' </summary>

    ''' <remarks></remarks>

 

    Private Sub GetSumData()Sub GetSumData()

        Dim dr As DataRow

 

        dtSum = New DataTable("TEST")

 

        dtSum = dt.Clone

 

        Dim rdm As Random = New Random

        dr = dtSum.NewRow()

        dr(0) = "合计"

 

        For i As Integer = 1 To dt.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

 

    End Sub

 

    ''' <summary>

    ''' 数据取得

    ''' </summary>

    ''' <returns></returns>

    ''' <remarks></remarks>

 

    Public Function GetData()Function GetData() As DataTable

 

        Dim dt As DataTable

        Dim dr As DataRow

 

        dt = New DataTable("TEST")

        dt.Columns.Add(New DataColumn("号码", GetType(String)))

        dt.Columns.Add(New DataColumn("数量1", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量2", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量3", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量4", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量5", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量6", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量7", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量8", GetType(Integer)))

        dt.Columns.Add(New DataColumn("数量9", GetType(Integer)))

 

        Dim rdm As Random = New Random

 

        For i As Integer = 10 To 80

            dr = dt.NewRow()

            dr(0) = "00" & i.ToString

            For j As Integer = 1 To 9

                dr(j) = rdm.Next(1000, 5000)

            Next

            dt.Rows.Add(dr)

        Next

 

        Return dt

    End Function

 

    ''' <summary>

    ''' 纵滚动条事件

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub VScrollBar1_Scroll()Sub VScrollBar1_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles VScrollBar1.Scroll

        'Debug.WriteLine(e.NewValue.ToString)

        Me.DataGridView1.FirstDisplayedScrollingRowIndex = e.NewValue  ROW_HEIGHT

 

    End Sub

 

    Private Sub Button2_Click()Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        Me.Close()

    End Sub

 

 

    ''' <summary>

    ''' 合计DataGridView的滚动条事件

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

 

    Private Sub DataGridViewSum_Scroll()Sub DataGridViewSum_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles DataGridViewSum.Scroll

        Me.DataGridView1.HorizontalScrollingOffset = e.NewValue

    End Sub

 

    ''' <summary>

    ''' 数据变更后重新合计

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub DataGridView1_CellValueChanged()Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged

        If e.ColumnIndex <= 0 Then

            Exit Sub

        End If

        ''DetaGridView中数据变化后重新合计

        Me.DataGridViewSum(e.ColumnIndex, 0).Value = dt.Compute("Sum(" + dt.Columns(e.ColumnIndex).ColumnName + ")", "true")

    End Sub

 

 

    ''' <summary>

    ''' 响应鼠标滚轴事件

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub DataGridViewSumRow_MouseWheel()Sub DataGridViewSumRow_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel

 

        If VScrollBar1.Visible = False Then

            Exit Sub

        End If

 

        If VScrollBar1.Value - ROW_HEIGHT < 0 And e.Delta > 0 Then

            VScrollBar1.Value = VScrollBar1.Minimum

            Exit Sub

        End If

 

        If VScrollBar1.Value + ROW_HEIGHT > VScrollBar1.Maximum And e.Delta < 0 Then

            VScrollBar1.Value = VScrollBar1.Maximum

            Exit Sub

        End If

 

        Try

            VScrollBar1.Value -= CInt(e.Delta / Math.Abs(e.Delta) * ROW_HEIGHT)

        Catch ex As Exception

            Debug.WriteLine("###########################")

            Debug.WriteLine("VScrollBar1.Value = " & VScrollBar1.Value)

            Debug.WriteLine("e.Delta = " & e.Delta)

            Debug.WriteLine("###########################")

        End Try

        Me.DataGridView1.FirstDisplayedScrollingRowIndex = VScrollBar1.Value  ROW_HEIGHT

 

    End Sub

End Class

*调整导出及打印的格式与显示一致;合计,详细参见第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事件 * 增加了导出和打印对应的支持,所见即所得的对齐方应用于式导出及打印。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MuskSu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值