将DataTable绑定到GridView,但GridViewRowCollection中没有行,尽管有GridView人口?

时间:2010-06-02 04:00:04

标签: c# asp.net gridview datatable

问题:我在页面的标记中编写了一个GridView。我在代码隐藏中编写了一个DataTable,它从一组自定义对象中获取数据。然后我将DataTable绑定到GridView。 (具体问题在下面提到了几个代码片段。)

GridView标记:

<asp:GridView ID="gvCart" runat="server" CssClass="pList" AutoGenerateColumns="false" DataKeyNames="ProductID">
        <Columns>
            <asp:BoundField DataField="ProductID" HeaderText="ProductID" />
            <asp:BoundField DataField="Name" HeaderText="ProductName" />
            <asp:ImageField DataImageUrlField="Thumbnail" HeaderText="Thumbnail"></asp:ImageField>
            <asp:BoundField DataField="Unit Price" HeaderText="Unit Price" />
            <asp:TemplateField HeaderText="Quantity">
                <ItemTemplate>
                    <asp:TextBox ID="Quantity" runat="server" Text="<%# Bind('Quantity') %>" Width="25px"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="Total Price" HeaderText="Total Price" />
        </Columns>
    </asp:GridView>

DataTable Code-Behind:

private void View(List<OrderItem> cart)
    {
        DataSet ds = new DataSet();
        DataTable dt = ds.Tables.Add("Cart");

        if (cart != null)
        {
            dt.Columns.Add("ProductID");
            dt.Columns.Add("Name");
            dt.Columns.Add("Thumbnail");
            dt.Columns.Add("Unit Price");
            dt.Columns.Add("Quantity");
            dt.Columns.Add("Total Price");

            foreach (OrderItem item in cart)
            {
                DataRow dr = dt.NewRow();

                dr["ProductID"] = item.productId.ToString();
                dr["Name"] = item.productName;
                dr["Thumbnail"] = ResolveUrl(item.productThumbnail);
                dr["Unit Price"] = "$" + item.productPrice.ToString();
                dr["Quantity"] = item.productQuantity.ToString();
                dr["Total Price"] = "$" + (item.productPrice * item.productQuantity).ToString();

                dt.Rows.Add(dr);
            }

            gvCart.DataSource = dt;
            gvCart.DataBind();
            gvCart.Width = 500;

            for (int counter = 0; counter < gvCart.Rows.Count; counter++)
            {
                gvCart.Rows[counter].Cells.Add(Common.createCell("<a href='cart.aspx?action=update&prodId=" +
                    gvCart.Rows[counter].Cells[0].Text + "'>Update</a><br /><a href='cart.aspx?action='action=remove&prodId=" +
                    gvCart.Rows[counter].Cells[0].Text + "/>Remove</a>"));
            }
        }
    }

foreach中出现错误 - GridViewRowCollection为空!

private void Update(string prodId)
    {
        List<OrderItem> cart = (List<OrderItem>)Session["cart"];
        int uQty = 0;

        foreach (GridViewRow gvr in gvCart.Rows)
        {
            if (gvr.RowType == DataControlRowType.DataRow)
            {
                if (gvr.Cells[0].Text == prodId)
                {
                    uQty = int.Parse(((TextBox)gvr.Cells[4].FindControl("Quantity")).Text);
                }
            }
        }

目标:我基本上试图找到一种方法来更新我的GridView中的数据(更重要的是我的购物车会话对象),而不必做我在网上看到的所有其他内容,例如利用OnRowUpdate等。请告诉我为什么gvCart.Rows是空的和/或如何在不使用OnRowUpdate等的情况下实现我的目标?当我执行此代码时,GridView会被填充,但由于某种原因,我无法访问代码隐藏中的任何行。

4 个答案:

答案 0 :(得分:0)

错误的原因是因为您正在检查

if (gvr.Cells[0].Text == prodId)

gvr中有gvCart.Rows,所以你需要先定义行的索引才能引用它的单元格。

有点像:

if (gvr[i].Cells[0].Text == prodId)

答案 1 :(得分:0)

您必须定义行的索引号以单独标识它。以下几行

if (gvr.Cells[0].Text == prodId)
 {
       uQty = int.Parse(((TextBox)gvr.Cells[4].FindControl("Quantity")).Text);
 }

应该是这样的:

if (gvr[i].Cells[0].Text == prodId)
 {
     uQty = int.Parse(((TextBox)gvr.Cells[4].FindControl("Quantity")).Text);
 }

答案 2 :(得分:0)

我复制了你的代码,在Postback上提供了带有CartItem对象列表的View方法,并且它有效 - 代码按预期进入循环。我做的唯一改变是注释了缩略图b / c我不想打扰图像。否则,我保留了标记和你的代码。您传递给View的列表绝对不是空的吗?也许如果你能澄清逻辑流程,我可以提供更多东西。作为旁注,为什么还要为创建数据集和数据表而烦恼呢?将列表直接绑定到网格会不会更容易?

答案 3 :(得分:0)

因此,当我编写这个项目的时候,我开始一天的休息时,用一大碗FAIL作为早餐,这是一件好事。我需要在Page_Load()中执行DataBind(),否则程序会认为GridView不在那里。问题解决了。感谢所有试图提供帮助的人。