给DataGridView增加一个合计行

DataGridView提供数据的显示和排序功能,但没有合计的功能,本人曾想过通过绑定DataView,然后直接给DataView增加一个,合计是可以显示出来,但通过列标题排序就很难控制了,绑定的做法很麻烦,因为很多动作不受控。绑定不行,只能自己创建DataGridView的列和行了,自己控制排序等。

为DataGridView增加列和行:

/// <summary>
        /// 根据DataTable创建DataGridView。
        /// </summary>
        /// <param name="table"></param>
        private void BuidGrid(DataTable table)
        {
            for (int i = 0; i < table.Columns.Count; i++)
            {
                DataColumn dcol = table.Columns[i];
                DataGridViewColumn column = new DataGridViewColumn(new DataGridViewTextBoxCell());
                dtgCount.Columns.Add(column);
                column.SortMode = DataGridViewColumnSortMode.Automatic;
                column.HeaderText = dcol.ColumnName;
                column.Name = dcol.ColumnName;
                if (i == 0)
                {
                    column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
                }
                else
                {
                    column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                    if (i == table.Columns.Count - 1)
                        column.DefaultCellStyle.BackColor = Color.Yellow;
                }
            }
            foreach (DataRow row in table.Rows)
            {
                int index = dtgCount.Rows.Add();
                DataGridViewRow vRow = dtgCount.Rows[index];
                for (int i = 0; i < table.Columns.Count; i++)
                {
                    vRow.Cells[i].Value = row[i];
                }
            }
            //增加多一个合计的行
            int countIndex = dtgCount.Rows.Add();
            DataGridViewRow countRow = dtgCount.Rows[countIndex];
            countRow.Cells[0].Value = "合计";
            for (int i = 1; i < table.Columns.Count; i++)
            {
                countRow.Cells[i].Value = table.Compute("Sum([" + table.Columns[i].ColumnName + "])", "");
                countRow.DefaultCellStyle.BackColor = Color.Yellow;
            }
        }

    这样合计行就在最下面了,现在要解决的是排序的问题了,在上面的数据中,除了第一列,其他列为Int32类型,合计行好像是字符串类型,没有深入研究原因。

 

        private void dtgCount_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
        {
            if (e.Column.Index == 0)
            {
                if (dtgCount.Rows[e.RowIndex1].Cells[0].Value.ToString() == "合计")
                {
                    if (e.Column.HeaderCell.SortGlyphDirection == SortOrder.Ascending)
                        e.SortResult = 1;
                    else
                        e.SortResult = -1;
                }
                else if (dtgCount.Rows[e.RowIndex2].Cells[0].Value.ToString() == "合计")
                {
                    if (e.Column.HeaderCell.SortGlyphDirection == SortOrder.Ascending)
                        e.SortResult = -1;
                    else
                        e.SortResult = 1;
                }
                else
                    e.SortResult = System.String.Compare(e.CellValue1.ToString(), e.CellValue2.ToString());

            }
            else
            {
                if (dtgCount.Rows[e.RowIndex1].Cells[0].Value.ToString() == "合计")
                {
                    if (e.Column.HeaderCell.SortGlyphDirection == SortOrder.Ascending)
                        e.SortResult = 1;
                    else
                        e.SortResult = -1;
                }
                else if (dtgCount.Rows[e.RowIndex2].Cells[0].Value.ToString() == "合计")
                {
                    if (e.Column.HeaderCell.SortGlyphDirection == SortOrder.Ascending)
                        e.SortResult = -1;
                    else
                        e.SortResult = 1;
                }
                else
                {
                    string strc1 = e.CellValue1.ToString();
                    string strc2 = e.CellValue2.ToString();
                    int c1 = string.IsNullOrEmpty(strc1) ? 0 : Convert.ToInt32(strc1);
                    int c2 = string.IsNullOrEmpty(strc2) ? 0 : Convert.ToInt32(strc2);
                    int result = c1 - c2;
                    e.SortResult = result > 0 ? 1 : (result < 0 ? -1 : 0);
                }
            }
            e.Handled = true;
        }

 

  排序的算法测试了很长时间,原因是不很清楚系统的快速排序算法,原以为合计行在最后,所以只对e.RowIndex2作判断,结果总是出问题,系统自动退出,可能排序使用的是异步线程吧,在系统里捕捉不到异常的,后来对e.RowIndex1和e.RowIndex2分别作判断,并根据SortOrder来确定返回的值,问题解决。在比较中可能有些操作效率不高,使用者可根据需要修改。

      如果想封装为通过的控制,可以重写DataSource属性,通过反射来生成行和列;重写OnSortCompare方法等,由于使用不多,所以本人只使用上面的方法,代码量也不多,比较灵活。

*调整导出及打印的格式与显示一致;合计,详细参见第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、付费专栏及课程。

余额充值