none
如何给GridView (批量更新) 添加各个列的合计 RRS feed

  • 问题

  •     参考《演练:GridView批量更新》 http://msdn.microsoft.com/zh-cn/library/aa992036  制作了一个GridView,把控件都转换为模板,现在想增加一项功能,给各个列在最底部添加一个合计。我曾在一个比较简单的GridView实现过这个功能,例如变量@Count,我在SQL中用 ‘;’ 隔开几个用于类似于@Count的合计变量,将他们的Direction="Output",前台再用
    protected void Selected(object sender, SqlDataSourceStatusEventArgs e)
        {
            string count = e.Command.Parameters["@Count"].Value.ToString();//取得行數
            string BuildingArea = e.Command.Parameters["@BuildingArea"].Value.ToString();//取得Sum值
            string MonthRent = e.Command.Parameters["@MonthRent"].Value.ToString();
            Label_Count.Text = "共有:<span style='color:red;'>" + count + "</span>项符合条件,面积合计:<span style='color:red'> " + BuildingArea + "</span> ㎡,理论月租金合计为:<span style='color:red;'>" + MonthRent + "</span>元。<span style='color:red;Font-Size:Small;'>查询正在履行的租赁合同请点击“合同类型”中的“租赁”,再点击“合同状态”中的“正在履行”</span>";
        }


        但是这次我遇到一个比较复杂的表,与以往不同的是:1.使用了“分页功能”,如果得到的结果一页不能显示完,显示出来的结果还是所有页的结果,这明显不对;2.要合计的列很多,且每个Label不一定能对其它对应的列,看起来不整齐。

     
        我想,GridView应该能方便的同时解决这两个问题,请各位大大不吝赐教,谢谢!


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!


    2012年3月27日 4:12

答案

全部回复

  • 针对第二个问题:

    不要用Label格式化,启用GridView的FooterRow(ShowFooterRow=true),然后直接:

    GridView1.FooterRow.Cells[索引].Text = 总数;

    第一个问题:分页汇总——

    每次分页的时候,在GridView_Paged,或者是Page_Load事件中这样做(Page_Load中如下代码请不要写到if(!IsPostBack){……}中去!:

    double total = 0.0;
    foreach(GridViewRow row in GridView1.Rows)
    {
       total+=Convert.ToDouble(row.Cells[索引].Text);
    }
    GridView1.FooterRow.Cells[索引].Text;   //注意启用ShowFooterRow=True

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月28日 2:24
  •     抱歉这么晚才回复您,我把您提供的方案测试了一下。

        我不是学编程的,还是个初学的雏鸟。。。 所以,您说的第一句 “不要用Label格式化,启用GridView的FooterRow(ShowFooterRow=true),”    我找了半天才找到这个属性,并设置为“true”。但接下来您说的“

    ,然后直接:

    GridView1.FooterRow.Cells[索引].Text = 总数;

    ”  ,这个我不懂。1.不知道这句话应该写在后台的哪里;2.不知道如何“依葫芦画瓢”的套用到我的代码中去。我发个链接,是我完整的代码 ,看看您能否有空 根据我的实际情况 更具体的指点一下。谢谢!

    http://social.msdn.microsoft.com/Forums/zh-CN/295/thread/f6ca5e7a-b617-4458-9dc8-5edd4ce1b159  


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!


    2012年3月30日 4:24
  • 这句话放到Paged事件,或者是Page_Load事件的(if(!IsPostBack)外边)——你用模板的话请用FindControl:

    double total = 0.0; foreach(GridViewRow row in GridView1.Rows) { total+=Convert.ToDouble((row.FindControl("Label的Id") as Label).Text); }

    GridView1.FooterRow.Cells[索引].Text=total; //“索引”代表GridView的列的序号,从0开始表示第一列……第N列的序号是N-1



       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月30日 4:57
  • 感谢您的回复,照您的“葫芦”我画出了“瓢”。
    过程:1。我的控件是TextBox而不是Label,代码中的Label改成了TextBox;
    2.一开始我在Page_Load事件中加上了代码:
            decimal total = 0;
            foreach (GridViewRow row in GridView1.Rows)
            {
                total += Convert.ToDecimal((row.FindControl("TextBox_MonthRentR01") as TextBox).Text);
            }




            GridView1.FooterRow.Cells[4].Text = Convert.ToString(total);  //“索引”代表GridView的列的序号,从0开始表示第一列……第N列的序号是N-1
     发现只有第一次打开页面时有“合计”,一旦点击“更新”,“合计”就不显示了 ,我只好在UpdateButton_Click事件中也加入这段代码。以下是我完整的代码,目前测试结果很完美。不知道这样写是否最科学最合理?   粗体字部分为增加部分。  
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    public partial class Default13 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //if (!IsPostBack)
            //{
            decimal total = 0;
            foreach (GridViewRow row in GridView1.Rows)
            {
                total += Convert.ToDecimal((row.FindControl("TextBox_MonthRentR01") as TextBox).Text);
            }
    
    
            GridView1.FooterRow.Cells[4].Text = Convert.ToString(total);  //“索引”代表GridView的列的序号,从0开始表示第一列……第N列的序号是N-1
            //}
        }
    
        private bool tableCopied = false;
        private System.Data.DataTable originalDataTable;
        protected void UpdateButton_Click(object sender, EventArgs e)
        {
            originalDataTable = (System.Data.DataTable)ViewState["originalValuesDataTable"];
    
            foreach (GridViewRow r in GridView1.Rows)
                if (IsRowModified(r)) { GridView1.UpdateRow(r.RowIndex, false); }
    
            // Rebind the Grid to repopulate the original values table.
            tableCopied = false;
            GridView1.DataBind();
    
            decimal total = 0;
            foreach (GridViewRow row in GridView1.Rows)
            {
                total += Convert.ToDecimal((row.FindControl("TextBox_MonthRentR01") as TextBox).Text);
            }
    
    
            GridView1.FooterRow.Cells[4].Text = Convert.ToString(total);  //“索引”代表GridView的列的序号,从0开始表示第一列……第N列的序号是N-1
            
    
        }
        protected void GirdView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
                if (!tableCopied)
                {
                    originalDataTable = ((System.Data.DataRowView)e.Row.DataItem).Row.Table.Copy();
                    ViewState["originalValuesDataTable"] = originalDataTable;
                    tableCopied = true;
                }
    
    
        }
    
        protected bool IsRowModified(GridViewRow r)
        {
            int currentID;
            DateTime currentLeaseDateToR;
            Decimal currentMonthRentR01;
            //string currentLastName;
            //string currentFirstName;
    
            currentID = Convert.ToInt32(GridView1.DataKeys[r.RowIndex].Value);
            //currentID = Convert.ToInt32(GridView1.DataKeys[0].Value);
    
            Response.Write(((TextBox)r.FindControl("TextBox_LeaseDateToR")).Text);
            if ((((TextBox)r.FindControl("TextBox_LeaseDateToR")).Text) != "")
                currentLeaseDateToR = Convert.ToDateTime(((TextBox)r.FindControl("TextBox_LeaseDateToR")).Text);
            else
                currentLeaseDateToR = Convert.ToDateTime("9999-01-01");
    
    
            //if ((((TextBox)r.FindControl("TextBox_LeaseDateToR")).Text) != "")
            //currentContractNumberR = ((Label)r.FindControl("Label_ContractNumberR")).Text;
            //else
            //    currentLeaseDateToR = Convert.ToDateTime("9999-01-01");
            
            
            if ((((TextBox)r.FindControl("TextBox_MonthRentR01")).Text) != "")
                currentMonthRentR01 = Convert.ToDecimal(((TextBox)r.FindControl("TextBox_MonthRentR01")).Text);
            else currentMonthRentR01 = 0;
            //currentMonthRentR01 = Convert.ToDecimal(((TextBox)r.FindControl("TextBox_MonthRentR01")).Text);
    
            System.Data.DataRow row =
                originalDataTable.Select(String.Format("PRID= {0}", currentID))[0];
    
            if (!currentLeaseDateToR.Equals(row["LeaseDateToR"].ToString())) { return true; }
            if (!currentMonthRentR01.Equals(row["MonthRentR01"].ToString())) { return true; }
    
            return false;
    
    
            
    
        }
    }



    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!


    2012年3月30日 8:56
  • 可以……这样你换一个方法——把我的代码放到GridView的

    DataBound 事件中,我估计Page_Load那个时候GridView尚未绑定,所以Rows是空的,导致点击回传页面之后根本没有进入for循环。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月30日 9:01