ASP.NET GridView跨分页选择条目仅保存当前页选中项问题求解
问题原因
- 核心问题1:提交按钮逻辑中仅遍历了GridView当前页面的行获取选中ID,跨页选中的其他页面的ID并未从存储选中项的
StItemDescIDs列表中读取,导致仅能拿到当前页的选中数据。 - 核心问题2:选中项同步逻辑仅在
OnPaging分页切换事件中执行,如果用户在最后一页选中条目后直接点击提交,当前页的最新选中状态还未同步到StItemDescIDs列表中,会出现最后一页选中项丢失的问题。
解决方法
步骤1:修改提交按钮btnSubmit的逻辑
首先新增当前页选中状态同步到StItemDescIDs的逻辑,然后直接从StItemDescIDs读取所有选中的ID进行后续操作,修改后的代码如下:
protected void btnSubmit(object sender, EventArgs e) { // 新增:先同步当前页的选中状态到StItemDescIDs,避免最后一页未切页导致的选中项丢失 foreach (GridViewRow gvr in gvItemDesc.Rows) { CheckBox chkSelect = gvr.FindControl("chkSelect") as CheckBox; if (chkSelect != null) { int StID = Convert.ToInt32(gvItemDesc.DataKeys[gvr.RowIndex]["StID"]); if (chkSelect.Checked && !this.StItemDescIDs.Contains(StID)) { this.StItemDescIDs.Add(StID); } else if (!chkSelect.Checked && this.StItemDescIDs.Contains(StID)) { this.StItemDescIDs.Remove(StID); } } } object id; //插入主父表 -> tblStationeryRequest string insertCmdtblStationeryRequest = @"INSERT INTO tblStationeryRequest (Department,RequestFor,UserName,Date,Email,Status) output inserted.StReqID VALUES (@Department,@RequestFor,@UserName,@Email,@Date,@Status)"; string Status = "Pending"; using (SqlConnection conn = new SqlConnection(cs)) { conn.Open(); using (SqlCommand sqlcmd = new SqlCommand(insertCmdtblStationeryRequest, conn)) { sqlcmd.Parameters.AddWithValue("@Department", ddlDept.SelectedItem.Text); sqlcmd.Parameters.AddWithValue("@RequestFor", ddlName.SelectedItem.Text); sqlcmd.Parameters.AddWithValue("@Date", lblCurrentDate.Text); sqlcmd.Parameters.AddWithValue("@UserName", SUserName.Text); sqlcmd.Parameters.AddWithValue("@Email", SUserEmail.Text); sqlcmd.Parameters.AddWithValue("@Status", Status); id = sqlcmd.ExecuteScalar(); } } // 改动:直接从StItemDescIDs获取所有跨页选中的ID,不再遍历当前页GridView if (this.StItemDescIDs.Count == 0) { // 可在此处添加未选中任何条目的提示逻辑 return; } string lblStID = string.Join(",", this.StItemDescIDs); // 注意:此处拼接SQL存在注入风险,生产环境建议改为参数化查询 string insertCmdtblRequestItemListID = @"INSERT INTO tblRequestItemListID(StReqID, StID, StItemDesc) select " + id.ToString() + ",StID,StItemDesc from tblStationeryItemlist where StID in (" + lblStID + ")"; using (SqlConnection conn = new SqlConnection(cs)) { conn.Open(); using (SqlCommand sqlcmd = new SqlCommand(insertCmdtblRequestItemListID, conn)) sqlcmd.ExecuteNonQuery(); } // 可选:提交成功后清空选中列表 this.StItemDescIDs.Clear(); }
额外优化建议
- 原代码中直接拼接IN子句的SQL字符串存在SQL注入风险,建议改为参数化查询实现IN条件的传参。
- 可在提交成功后跳转页面或给出操作成功提示,提升用户体验。
内容的提问来源于stack exchange,提问作者Zan
相关产品推荐
相关产品推荐

