给DataGridView添加底部合计行的一种方法[转载]

 

DataGridView是使用很多的控件,可是却没有底部合计行的功能,在做一个小项目时有很多地方要用到,就通过下面的方法实现了这一功能:

把下面  

#region 添加DataGridView底行合计数 的四个方法   
和  
#endregion   添加DataGridView底行合计数 的四个方法
之间的 代码拷贝到你的程序中

然后再 给要计算合计的 DataGridView 对象(此处假定为dataGridView1) 绑定 下面的方法及 数据表   则可:

这里假设通过点击 按钮 之后 绑定

private void button1_Click(object sender, EventArgs e)
   {

      dataGridView1.DataSourceChanged += new EventHandler(dataGridView_DataSourceChanged);
    dataGridView1.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(dataGridView_ColumnHeaderMouseClick);
    dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView_CellValueChanged);
    dataGridView1.AllowUserToAddRows = false;
    dataGridView1.DataSource = 这里是要绑定的数据表;

   }

 

#region 添加DataGridView底行合计数 的四个方法
   /// <summary>
   /// 计算合计算
   /// </summary>
   /// <param name="dgv">要计算的DataGridView</param>
   private void SumDataGridView(DataGridView dgv)
   {

    #region 计算合计数
    //DataGridView dgv = (DataGridView)sender;
    if (dgv.DataSource == null) return;
    DataTable dt = (DataTable)dgv.DataSource;
    if (dt.Rows.Count < 1) return;
    decimal[] tal = new decimal[dt.Columns.Count];

    DataRow ndr = dt.NewRow();

    string talc = "";

    int number = 1;
    foreach (DataRow dr in dt.Rows)
    {
     dr["@xu.Hao"] = number++;
     int n = 0;
     foreach (DataColumn dc in dt.Columns)
     {


      if (talc == "" && dc.DataType.Name.ToUpper().IndexOf("STRING") >= 0) talc = dc.ColumnName;


      if (dc.DataType.IsValueType)
      {
       string hej = dr[dc.ColumnName].ToString();
       try
       {
        if (hej != string.Empty) tal[n] += decimal.Parse(hej);
       }
       catch (Exception) { }
       //if (hej != string.Empty) tal[n] += decimal.Parse(hej);
      }


      n++;
     }
    }

    ndr.BeginEdit();
    for (int i = 0; i < dt.Columns.Count; i++)
    {
     if (tal[i] != 0)
      ndr[i] = tal[i];
    }
    ndr["@xu.Hao"] = ((int)(dt.Rows.Count + 1)).ToString();
    if (talc != "") ndr[talc] = "[合计]";
    ndr.EndEdit();
    dt.Rows.Add(ndr);

    dgv.Rows[dgv.Rows.Count - 1].DefaultCellStyle.BackColor = Color.FromArgb(255, 255, 210);


    if (dgv.Tag == null)
    {
     foreach (DataGridViewColumn dgvc in dgv.Columns)
     {
      dgvc.SortMode = DataGridViewColumnSortMode.Programmatic;
     }
    }


    dgv.Tag = ndr;

    #endregion


   }
   private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
   {//
    //直接拷贝代码

    DataGridView sortDgv = (DataGridView)sender;
    int fx = 0;
    if (sortDgv.AccessibleDescription == null)
    {
     fx = 1;
    }
    else
    {
     fx = int.Parse(sortDgv.AccessibleDescription);
     fx = (fx == 0 ? 1 : 0);
    }
    sortDgv.AccessibleDescription = fx.ToString();
    if (sortDgv.Columns[e.ColumnIndex].Name == "@xu.Hao") return;
    DataGridViewColumn nCol = sortDgv.Columns[e.ColumnIndex];

    if (nCol.DataPropertyName == string.Empty) return;

    if (nCol != null)
    {
     sortDgv.Sort(nCol, fx == 0 ? ListSortDirection.Ascending : ListSortDirection.Descending);

    }
    //--
    DataRow dr = (DataRow)sortDgv.Tag;
    DataTable dt = (DataTable)sortDgv.DataSource;
    DataRow ndr = dt.NewRow();
    ndr.BeginEdit();
    for (int i = 0; i < dt.Columns.Count; i++)
    {
     ndr[i] = dr[i];
    }
    dt.Rows.Remove(dr);


    //if (e.ColumnIndex != 0)
    {
     int n = 1;
     for (int i = 0; i < sortDgv.Rows.Count; i++)
     {
      DataGridViewRow dgRow = sortDgv.Rows[i];
      DataRowView drv = (DataRowView)dgRow.DataBoundItem;
      DataRow tdr = drv.Row;
      tdr.BeginEdit();
      tdr["@xu.Hao"] = n;
      n++;
      tdr.EndEdit();

     }
     sortDgv.Refresh();
     sortDgv.RefreshEdit();

    }
    ndr["@xu.Hao"] = ((int)(dt.Rows.Count + 1)).ToString();
    ndr.EndEdit();
    dt.Rows.Add(ndr);
    sortDgv.Tag = ndr;

    //--
    sortDgv.Sort(sortDgv.Columns["@xu.Hao"], ListSortDirection.Ascending);
    sortDgv.Columns["@xu.Hao"].HeaderCell.SortGlyphDirection = SortOrder.None;
    nCol.HeaderCell.SortGlyphDirection = fx == 0 ? SortOrder.Ascending : SortOrder.Descending;
    sortDgv.Rows[sortDgv.Rows.Count - 1].DefaultCellStyle.BackColor = Color.FromArgb(255, 255, 210);

   }
   private void dataGridView_DataSourceChanged(object sender, EventArgs e)
   {
    DataGridView dgv = (DataGridView)sender;
    DataTable dt = (DataTable)dgv.DataSource;
    if (dt == null) return;
    decimal[] tal = new decimal[dt.Columns.Count];
    if (dt.Columns.IndexOf("@xu.Hao") < 0)
    {
     DataColumn dc = new DataColumn("@xu.Hao", System.Type.GetType("System.Int32"));
     dt.Columns.Add(dc);
     dgv.Columns["@xu.Hao"].DisplayIndex = 0;
     dgv.Columns["@xu.Hao"].HeaderText = "#";

     dgv.Columns["@xu.Hao"].SortMode = DataGridViewColumnSortMode.Programmatic;
     dgv.AutoResizeColumn(dgv.Columns["@xu.Hao"].Index); 

     dgv.Columns["@xu.Hao"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
    }
    SumDataGridView(dgv);
   }
   private void dataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
   {//
    DataGridView dgv = (DataGridView)sender;
    if (dgv.Tag == null || e.RowIndex < 0 || e.RowIndex == dgv.Rows.Count - 1) return;

    string col = dgv.Columns[e.ColumnIndex].DataPropertyName;
    if (col == string.Empty) return;
    if (((DataRowView)dgv.Rows[e.RowIndex].DataBoundItem).Row.Table.Columns[col].DataType.IsValueType)
    {
     decimal tal = 0;
     foreach (DataGridViewRow dgvr in dgv.Rows)
     {
      if (dgvr.Index != dgv.Rows.Count - 1)
      {
       string hej = dgvr.Cells[e.ColumnIndex].Value.ToString();
       if (hej != string.Empty) tal += decimal.Parse(hej);
      }
     }
     if (tal == 0)
      dgv[e.ColumnIndex, dgv.Rows.Count - 1].Value = DBNull.Value;
     else
      dgv[e.ColumnIndex, dgv.Rows.Count - 1].Value = tal;
    }
   }
   #endregion   添加DataGridView底行合计数 的四个方法

 

我在项目中多处运行通过,但不知道通用性如何?!
欢迎交流!

*调整导出及打印的格式与显示一致;合计,详细参见第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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值