C# 每次名称更改时显示网格中的行总数

C# 每次名称更改时显示网格中的行总数,c#,asp.net,gridview,C#,Asp.net,Gridview,我试图在我的页面上显示一个网格,每次网格中的名称更改时,都会显示该名称的总数。但是,我不断收到一个错误,即对象未设置为对象的实例这是我正在尝试的语法,有人能看看并告诉我我做错了什么吗 <asp:GridView ID="gvTest" runat="server" OnDataBound = "gvODB" OnRowCreated = "gvORC" > <Columns> <asp:BoundField DataField="" HeaderText="

我试图在我的页面上显示一个网格,每次网格中的名称更改时,都会显示该名称的总数。但是,我不断收到一个错误,即
对象未设置为对象的实例
这是我正在尝试的语法,有人能看看并告诉我我做错了什么吗

<asp:GridView ID="gvTest" runat="server" OnDataBound = "gvODB" OnRowCreated = "gvORC" >
<Columns>
    <asp:BoundField DataField="" HeaderText="userID"></asp:BoundField>
    <asp:BoundField DataField="employeename" HeaderText="Name"></asp:BoundField>
    <asp:BoundField DataField="hoursworked" HeaderText="Daily Hours"></asp:BoundField>
</Columns>
</asp:GridView>


private int currentId = 0;
private decimal subTotal = 0;
private decimal total = 0;
private int subTotalRowIndex = 0;

protected void gvORC(object sender, GridViewRowEventArgs e)
{
  DataTable dt = new DataTable();
  subTotal = 0;
  try
  {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        dt = (e.Row.DataItem as DataRowView).DataView.Table;
        int userID = Convert.ToInt32(dt.Rows[e.Row.RowIndex]["userID"]);
        total += Convert.ToDecimal(dt.Rows[e.Row.RowIndex]["hoursworked"]);
        if (userID != currentId)
        {
            if (e.Row.RowIndex > 0)
            {
                for (int i = subTotalRowIndex; i < e.Row.RowIndex; i++)
                {
                    subTotal += Convert.ToDecimal(gvTest.Rows[i].Cells[2].Text);
                }
                this.AddTotalRow("Total", subTotal.ToString("N2"));
                subTotalRowIndex = e.Row.RowIndex;
            }
            currentId = userID;
        }
    }
  }
  catch (Exception exception)
  {
    throw exception;
  }
}
protected void AddTotalRow(string labelText, string value)
{
  GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
  row.BackColor = ColorTranslator.FromHtml("#F9F9F9");
  row.Cells.AddRange(new TableCell[3] { new TableCell (), //Empty Cell
                            new TableCell { Text = labelText,     HorizontalAlign = HorizontalAlign.Right}, 
                            new TableCell { Text = value, HorizontalAlign = HorizontalAlign.Right } });

    gvTest.Controls[0].Controls.Add(row);

}

私有int currentId=0;
私有小数小计=0;
私有十进制总数=0;
私有整数小计rowIndex=0;
受保护的void gvORC(对象发送方,GridViewRowEventArgs e)
{
DataTable dt=新的DataTable();
小计=0;
尝试
{
如果(e.Row.RowType==DataControlRowType.DataRow)
{
dt=(e.Row.DataItem作为DataRowView).DataView.Table;
int userID=Convert.ToInt32(dt.Rows[e.Row.RowIndex][“userID]”);
总计+=转换为小数(dt.Rows[e.Row.RowIndex][“工作小时数]);
if(userID!=currentId)
{
如果(e.Row.RowIndex>0)
{
对于(int i=小计RowIndex;i
编辑-- 网格将返回用户ID、用户名和工作时间。我希望显示返回的每个用户名的总数。差不多 用户名小时数 1646红色16 1646红色8 总数24 1812蓝色6 1812蓝色8 总数14


现在将始终返回用户名、名称和小时数,唯一返回空值的时间是将所有结果添加到网格中时。

我们的想法是生成显示简单“报告”的html。有很多方法可以做到这一点。如果数据是只读的,那么使用网格不如只构建一个
或一组div等。您可以查看Repeater或ListView,但这里我演示了一个简单的
元素:

aspx标记包含一个简单的asp:表,其中包含runat server:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">

<asp:Table runat="server" ID="usertbl" border="1">

</asp:Table>

</asp:Content>
最后的结果是:

没有人能用您提供的信息写出一个好的答案,但一般来说,您的例外情况几乎肯定是,您可以通过索引访问一个项目,然后在不进行任何空检查的情况下访问属性。另外,您知道页脚模板吗?这个问题缺乏上下文,我无法确切了解“网格中的名称每次更改”的含义。可能页脚模板在这里不合适。要进行空检查,只需测试
是否(x==null)
。例如,检查gvTest是否为null,然后测试gvTest.Rows是否为null,然后测试gvTest.Rows[I]是否为null,然后测试gvTest.Rows[I]。Cells是否为null,等等@Crowcoder-请参阅我的编辑,这有助于澄清问题吗?如果网格是只读的,那么使用某种中继器控件甚至报告将更容易实现。@Crowcoder-我如何使用中继器控件来实现这一点?哦,看起来太完美了!!它们是我将单词“Total”添加到实际总计行的一种方式吗?如果没有,那也没关系,但从视觉上看那会很好。是的,数据是只读的。是的,您可以在其中一个空单元格中添加“总计”或任何您想要的内容。
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Contrived Data table just because I need some data to demonstrate.
            //I assume you are or can acquire a DataTable with your current solution.
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("UserID", typeof(int)));
            dt.Columns.Add(new DataColumn("UserName", typeof(string)));
            dt.Columns.Add(new DataColumn("Hours", typeof(int)));

            DataRow row = dt.NewRow();
            row[0] = 1646;
            row[1] = "Red";
            row[2] = 16;
            dt.Rows.Add(row);

            row = dt.NewRow();
            row[0] = 1646;
            row[1] = "Red";
            row[2] = 8;
            dt.Rows.Add(row);

            row = dt.NewRow();
            row[0] = 1812;
            row[1] = "Blue";
            row[2] = 6;
            dt.Rows.Add(row);

            row = dt.NewRow();
            row[0] = 1812;
            row[1] = "Blue";
            row[2] = 14;
            dt.Rows.Add(row);

            //Simplify accumualtor logic by grouping on Userid
            var users = dt.AsEnumerable().GroupBy(u => u[0]);

            //For each group (each user id)
            foreach (var item in users)
            {
                //adds the user hours
                int accumulator = 0;

                //For each set or rows in group
                foreach (var dr in item)
                {
                    accumulator += int.Parse(dr[2].ToString());

                    //Create a table row
                    TableRow tr = new TableRow();

                    //Add the cells to the table row
                    TableCell userIdCell = new TableCell();
                    userIdCell.Text = item.Key.ToString();
                    tr.Cells.Add(userIdCell);

                    TableCell userNameCell = new TableCell();
                    userNameCell.Text = dr[1].ToString();
                    tr.Cells.Add(userNameCell);

                    TableCell hoursCell = new TableCell();
                    hoursCell.Text = dr[2].ToString();
                    tr.Cells.Add(hoursCell);

                    //Add the row to the table
                    usertbl.Rows.Add(tr);
                }

                //create summary row
                TableRow totalRow = new TableRow();
                //Skip a cells
                totalRow.Cells.Add(new TableCell());
                totalRow.Cells.Add(new TableCell());
                //total cell
                TableCell userTotalCell = new TableCell();
                userTotalCell.Text = accumulator.ToString();
                totalRow.Cells.Add(userTotalCell);

                //Finally add the row
                usertbl.Rows.Add(totalRow);
            }
        }
    }
}