【问题标题】:Binding DataTable To GridView, But No Rows In GridViewRowCollection Despite GridView Population?将 DataTable 绑定到 GridView,但 GridViewRowCollection 中没有行,尽管有 GridView 填充?
【发布时间】:2010-06-02 04:00:04
【问题描述】:

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

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 代码隐藏:

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(更重要的是我的购物车 Session 对象)中的数据,而不必执行我在网上看到的所有其他事情,例如使用 OnRowUpdate 等。有人可以请告诉我为什么 gvCart.Rows 是空的和/或如何在不使用 OnRowUpdate 等的情况下实现我的目标?当我执行此代码时,GridView 会被填充,但由于某种原因,我无法在代码隐藏中访问它的任何行。

【问题讨论】:

    标签: c# asp.net gridview datatable


    【解决方案1】:

    你出错的原因是因为你正在检查

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

    gvr里面有gvCart.Rows,所以需要先定义行的索引才能引用它的Cells。

    有点像:

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

    【讨论】:

    • 我很欣赏快速响应,但我很困惑。编译器甚至没有进入 foreach。当我将鼠标悬停在“gvCart.Rows”上并观察“Count”属性时,它是 0。这就是我难住的地方。
    • 您能否概述一下您是如何调用每个方法的?
    • 在我的 cart.aspx 页面上,我在 Page_Load 的查询字符串中查找某个变量,该变量确定调用什么方法,例如:string action = Request.QueryString["action"];字符串 prodId = Request.QuerySTring["prodId"]; if(action == "update") { this.Update(prodId); } else if (action == "remove") { this.Remove(prodId);无论如何,如果我的 DataSource 没有正确设置,我不会在 GridView 中获得不正确的数量(很可能是 0)可见行吗?我的 GridView 中的数据是可见的,但是在我的一个按钮被单击后我无法访问行数。 :-(
    【解决方案2】:

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

    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);
     }
    

    【讨论】:

    • 我很欣赏快速响应,但我很困惑。编译器甚至没有进入 foreach。当我将鼠标悬停在“gvCart.Rows”上并观察“Count”属性时,它是 0。这就是我难住的地方。
    • foreach (GridViewRow gvr in gvCart.Rows) 应该像 foreach (GridViewRow gvr in gvCart.Rows.Count)
    • 那行不通,请阅读他的问题:它说行数的计数为 0。
    【解决方案3】:

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

    【讨论】:

    • 我尝试直接绑定,但无法访问列来更改列名。 :-( 无论如何,列表肯定不是空的。如果它是空的,那么 GridView 将不会填充。GridView 可以从 List/DataTable 中很好地填充我正在喂它,只是出于任何原因,当我通过我的更新进行回发时链接,它认为 GridView.Rows 集合是空的。:-(
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 2010-10-30
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      相关资源
      最近更新 更多