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传递行索引
- 修改ASPX中的ButtonField,绑定行索引到
CommandArgument:
<asp:ButtonField ButtonType="Button" CommandName="minusQuantity" Text="-" CommandArgument='<%# Container.DataItemIndex %>' /> <asp:ButtonField ButtonType="Button" CommandName="addQuantity" Text="+" CommandArgument='<%# Container.DataItemIndex %>' />
- 修改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"); }
额外优化建议
- 避免通过Cells索引取值,可添加隐藏列存储唯一标识(如menuItemID),用ID更新数据比itemName更可靠;
- 使用
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
相关产品推荐
相关产品推荐

