You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GridView.SelectedRow返回Null问题求助(附完整代码)

问题:ASP.NET GridView RowCommand事件中SelectedRow为Null的解决办法

我在ASP.NET项目中开发购物车功能,通过SQL数据库加载数据绑定到GridView,加载数据的代码如下:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        LoadCart();
    }
}
protected void LoadCart()
{
    string _connStr = ConfigurationManager.ConnectionStrings["CartDB"].ConnectionString;
    SqlConnection SQLConn = new SqlConnection(_connStr);
    SqlDataAdapter SQLAdapter = new SqlDataAdapter("SELECT M.menuItemName, M.menuItemImage,totalQuantity, M.menuItemPrice * totalQuantity Total_Price" +
        " FROM Cart C INNER JOIN itemSelected I ON C.username + C.itemSelectedID = I.username + I.itemSelectedID" +
        " INNER JOIN menuItem M ON I.menuItemID + I.stallID = M.menuItemID + M.stallID", SQLConn);
    
    DataTable DT = new DataTable();
    SQLAdapter.Fill(DT);
    CartGridView.DataSource = DT;
    CartGridView.DataBind();
    LoadPrice();
}
protected void LoadPrice()
{
    string _connStr = ConfigurationManager.ConnectionStrings["CartDB"].ConnectionString;
    SqlConnection SQLConn = new SqlConnection(_connStr);
    SqlCommand cmd = new SqlCommand("SELECT SUM(M.menuItemPrice * totalQuantity)tabulatedPrice" +
        " FROM Cart C INNER JOIN itemSelected I ON C.username + C.itemSelectedID = I.username + I.itemSelectedID" +
        " INNER JOIN menuItem M ON I.menuItemID + I.stallID = M.menuItemID + M.stallID", SQLConn);
    SQLConn.Open();
    lbl_TotalPrice.Text = cmd.ExecuteScalar().ToString(); 
    SQLConn.Close();
}

点击GridView中的“+”“-”按钮触发RowCommand事件时,CartGridView.SelectedRow返回Null,无法获取对应行数据,相关代码如下:

protected void CartGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    int result = 0;
    Cart cart = new Cart();
    GridViewRow row = CartGridView.SelectedRow;
    string itemName = row.Cells[0].Text;
    if (e.CommandName == "minusQuantity")
    {
        int quantity = int.Parse(row.Cells[3].Text) - 1;
        if (quantity > 0)
        {
            cart.CartUpdateQuantity(quantity, itemName);
        }
        else
        {
            result = cart.CartDelete(itemName);
        }

    }
    else if (e.CommandName == "addQuantity")
    {
        int quantity = int.Parse(row.Cells[3].Text) + 1;
            cart.CartUpdateQuantity(quantity, itemName);
    }
    Response.Redirect("UserShoppingCart.aspx");
}

ASPX页面代码:

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
    <h1>Cart<table class="nav-justified">
        <tr>
            <td style="width: 860px" class="modal-lg">Product</td>
            <td style="width: 698px">Images</td>
            <td class="modal-lg" style="width: 1265px">Quantity</td>
            <td>
                Price</td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:GridView ID="CartGridView" runat="server" AutoGenerateColumns="False" Width="1514px" OnRowCommand="CartGridView_RowCommand" >
                    <Columns>
                        <asp:BoundField HeaderText="Product" ShowHeader="False" DataField="menuItemName" />
                        <asp:BoundField HeaderText="Images" ShowHeader="False" DataField="menuItemImage" />
                        <asp:ButtonField ButtonType="Button" CommandName="minusQuantity" Text="-" />
                        <asp:BoundField HeaderText="Quantity" DataField="totalQuantity" />
                        <asp:ButtonField ButtonType="Button" CommandName="addQuantity" Text="+" />
                        <asp:BoundField DataField="Total_Price" HeaderText="Price" ShowHeader="False" />
                    </Columns>
                </asp:GridView>
            </td>
        </tr>
        <tr>
            <td style="height: 39px; " colspan="3">Total:<asp:Label ID="lbl_TotalPrice" runat="server"></asp:Label>
            </td>
            <td style="height: 39px; width:50px;">
            </td>
        </tr>
        </table>
    </h1>
</asp:Content>

我曾尝试通过string itemName = CartGridView.Rows[0].Cells[0].Text;获取数据,但仅对第一行有效,不确定如何处理后续行。请问该问题是否与使用SQL表作为数据源有关?求解决办法。


问题原因

SelectedRow只有在GridView设置了AutoGenerateSelectButton="True"或手动添加Select按钮,且用户点击Select按钮后才会赋值。你这里的“+”“-”是普通Command按钮,不会触发行选中状态,因此SelectedRow返回Null,和SQL数据源无关,是获取行的方式错误。

解决办法

方法1:通过CommandArgument传递行索引

  1. 修改ASPX中的ButtonField,绑定行索引到CommandArgument:
<asp:ButtonField ButtonType="Button" CommandName="minusQuantity" Text="-" CommandArgument='<%# Container.DataItemIndex %>' />
<asp:ButtonField ButtonType="Button" CommandName="addQuantity" Text="+" CommandArgument='<%# Container.DataItemIndex %>' />
  1. 修改RowCommand事件代码,通过e.CommandArgument获取对应行:
protected void CartGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    int result = 0;
    Cart cart = new Cart();
    // 获取点击的行索引
    int rowIndex = Convert.ToInt32(e.CommandArgument);
    GridViewRow row = CartGridView.Rows[rowIndex];
    string itemName = row.Cells[0].Text;

    if (e.CommandName == "minusQuantity")
    {
        int quantity = int.Parse(row.Cells[3].Text) - 1;
        if (quantity > 0)
        {
            cart.CartUpdateQuantity(quantity, itemName);
        }
        else
        {
            result = cart.CartDelete(itemName);
        }
    }
    else if (e.CommandName == "addQuantity")
    {
        int quantity = int.Parse(row.Cells[3].Text) + 1;
        cart.CartUpdateQuantity(quantity, itemName);
    }
    Response.Redirect("UserShoppingCart.aspx");
}

方法2:通过按钮的NamingContainer获取GridViewRow

无需修改ASPX,直接从触发事件的按钮向上查找父容器:

protected void CartGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
    int result = 0;
    Cart cart = new Cart();
    // 获取触发事件的按钮,再找到对应的GridViewRow
    Button btn = (Button)e.CommandSource;
    GridViewRow row = (GridViewRow)btn.NamingContainer;
    string itemName = row.Cells[0].Text;

    if (e.CommandName == "minusQuantity")
    {
        int quantity = int.Parse(row.Cells[3].Text) - 1;
        if (quantity > 0)
        {
            cart.CartUpdateQuantity(quantity, itemName);
        }
        else
        {
            result = cart.CartDelete(itemName);
        }
    }
    else if (e.CommandName == "addQuantity")
    {
        int quantity = int.Parse(row.Cells[3].Text) + 1;
        cart.CartUpdateQuantity(quantity, itemName);
    }
    Response.Redirect("UserShoppingCart.aspx");
}

额外优化建议

  1. 避免通过Cells索引取值,可添加隐藏列存储唯一标识(如menuItemID),用ID更新数据比itemName更可靠;
  2. 使用using语句管理SQL连接,避免连接泄漏:
protected void LoadCart()
{
    string _connStr = ConfigurationManager.ConnectionStrings["CartDB"].ConnectionString;
    using(SqlConnection SQLConn = new SqlConnection(_connStr))
    {
        SqlDataAdapter SQLAdapter = new SqlDataAdapter("SELECT M.menuItemName, M.menuItemImage,totalQuantity, M.menuItemPrice * totalQuantity Total_Price" +
            " FROM Cart C INNER JOIN itemSelected I ON C.username + C.itemSelectedID = I.username + I.itemSelectedID" +
            " INNER JOIN menuItem M ON I.menuItemID + I.stallID = M.menuItemID + M.stallID", SQLConn);
        
        DataTable DT = new DataTable();
        SQLAdapter.Fill(DT);
        CartGridView.DataSource = DT;
        CartGridView.DataBind();
        LoadPrice();
    }
}

protected void LoadPrice()
{
    string _connStr = ConfigurationManager.ConnectionStrings["CartDB"].ConnectionString;
    using(SqlConnection SQLConn = new SqlConnection(_connStr))
    {
        SqlCommand cmd = new SqlCommand("SELECT SUM(M.menuItemPrice * totalQuantity)tabulatedPrice" +
            " FROM Cart C INNER JOIN itemSelected I ON C.username + C.itemSelectedID = I.username + I.itemSelectedID" +
            " INNER JOIN menuItem M ON I.menuItemID + I.stallID = M.menuItemID + M.stallID", SQLConn);
        SQLConn.Open();
        var total = cmd.ExecuteScalar();
        lbl_TotalPrice.Text = total != DBNull.Value ? total.ToString() : "0";
    }
}

内容的提问来源于stack exchange,提问作者SpunkkyD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:45:43