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

ASP.NET GridView外按钮复选框判断异常问题求助

问题描述

我有一个包含多行数据的ASP.NET GridView,每行都配置了Checkbox控件,GridView外部设有Approve和Reject两个按钮。需求是:若用户未勾选任何Checkbox就直接点击按钮,需弹出提示框。

但目前存在异常:当GridView中有3行数据,勾选中间行的Checkbox后点击按钮,仍然会弹出"未勾选"的提示框,请问如何解决?


相关代码

前端ASPX代码

<asp:GridView ID="rptHotoIPDataInfo" runat="server" AutoGenerateColumns="false" CssClass="appRejTableOuter appRejTable" Visible="true"
                AllowPaging="true" PageSize="10" OnPageIndexChanging="rptHotoIPDataInfo_PageIndexChanging"
                DataKeyNames="SAP_ID" OnRowEditing="rptHotoIPDataInfo_RowEditing" OnRowUpdating="rptHotoIPDataInfo_RowUpdating"
                OnRowCancelingEdit="rptHotoIPDataInfo_RowCancelingEdit" OnRowDataBound="rptHotoIPDataInfo_RowDataBound"
                OnRowCommand="rptHotoIPDataInfo_RowCommand" EnableViewState="true">

                <Columns>
                    <asp:TemplateField HeaderStyle-CssClass="appRejTable">
                        <ItemTemplate>
                            <asp:CheckBox ID="chkRow" runat="server" Checked="false" AutoPostBack="true" CssClass="appRejCheckbox" />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="ID" ItemStyle-Width="50px" Visible="true">
                        <ItemTemplate>
                            <asp:Label ID="lbl_ID" runat="server" Text='<%#Eval("ID") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Rejected Remarks" HeaderStyle-CssClass="appRejTable">
                        <ItemTemplate>
                            <asp:TextBox ID="txtRemarks" Rows="3" Text='<%# Eval("REJECT_REMARKS") %>' runat="server" CssClass="appRejInput"></asp:TextBox>
                        </ItemTemplate>
                    </asp:TemplateField>

                    <asp:BoundField DataField="SAP_ID" HeaderText="SAP ID"></asp:BoundField>
                    <asp:BoundField DataField="CHANGEREQUEST_ID" HeaderText="Change Request ID"></asp:BoundField>
                    <asp:BoundField DataField="R4GSTATE_CODE" HeaderText="State Code"></asp:BoundField>
                    <asp:BoundField DataField="HOTO_STATUS" HeaderText="Hoto Status"></asp:BoundField>
                    <asp:BoundField DataField="CR_Justifications" HeaderText="CR Justifications"></asp:BoundField>
                    <asp:BoundField DataField="APPROVE_REJECT" HeaderText="Status"></asp:BoundField>
                    <asp:BoundField DataField="LAST_UPDATED_BY" HeaderText="Last Updated by"></asp:BoundField>
                </Columns>
            </asp:GridView>

<asp:Button ID="btnApproveSite" runat="server" CssClass="btn btn-blue" Text="Approve"
                CommandName="Approve" CommandArgument='<%#Eval("SAP_ID") %>' OnClick="btnApproveSite_Click" />

            <asp:Button ID="btnRejectSite" runat="server" CssClass="btn btn-blue" Text="Reject"
                CommandName="Reject" CommandArgument='<%#Eval("SAP_ID") %>' OnClick="btnRejectSite_Click" />

后台C#代码

protected void btnRejectSite_Click(object sender, EventArgs e)
{
    string strRemarks = string.Empty;
    string strID = string.Empty;
    string strCurrentUser = string.Empty;
    string strBtnReject = string.Empty;
    bool isUpdateRow = false;

    foreach (GridViewRow row in rptHotoIPDataInfo.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            CheckBox chkRow = (row.Cells[0].FindControl("chkRow") as CheckBox);
            TextBox txtRemarks = (TextBox)row.FindControl("txtRemarks");
            strID = (row.Cells[1].FindControl("lbl_ID") as Label).Text;

            strBtnReject = btnRejectSite.Text;

            if (chkRow.Checked == true && strBtnReject == "Reject")
            {
                strRemarks = txtRemarks.Text;
                strCurrentUser = CurrentUserName;
                int intGroupID = CurrentUserGroupID;

                if (strRemarks != "")
                {
                    isUpdateRow = UpdateRejectInfo(strID, strRemarks, strCurrentUser, intGroupID, strCurrentUser);

                    if (isUpdateRow)
                    {
                        BindHotoIPNonIPSubmit();
                    }
                }
                else
                {
                    ScriptManager.RegisterStartupScript(this, typeof(Page), "Alert", "<script>alert('Rejected Remarks cannot be blank');</script>", false);
                }
            }
            else
            {
                ScriptManager.RegisterStartupScript(this, typeof(Page), "Alert", "<script>alert('For Rejection, first you need to check the Checkbox');</script>", false);
            }
        }
    }
}

解决方案

问题根源

当前代码逻辑错误:遍历GridView每一行时,只要某一行未勾选Checkbox,就会触发else分支弹出提示。比如3行数据中仅中间行勾选,循环到第一行和第三行时,都会执行else里的提示代码,导致即使有勾选行,用户仍会看到未勾选的提示。

修复步骤

  1. 先遍历所有行,判断是否存在至少一个勾选的Checkbox;
  2. 如果没有勾选的行,直接弹出提示并终止方法;
  3. 如果有勾选的行,再遍历处理每一行的勾选逻辑,同时处理备注为空的情况;
  4. 提示框使用唯一key,避免被后续提示覆盖。

修改后的后台代码

protected void btnRejectSite_Click(object sender, EventArgs e)
{
    string strRemarks = string.Empty;
    string strID = string.Empty;
    string strCurrentUser = string.Empty;
    bool isUpdateRow = false;
    bool hasCheckedRow = false;

    // 第一步:检查是否有勾选的行
    foreach (GridViewRow row in rptHotoIPDataInfo.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            CheckBox chkRow = row.FindControl("chkRow") as CheckBox;
            if (chkRow != null && chkRow.Checked)
            {
                hasCheckedRow = true;
                break; // 找到一个勾选行就停止遍历
            }
        }
    }

    // 无勾选行时弹出提示并返回
    if (!hasCheckedRow)
    {
        ScriptManager.RegisterStartupScript(this, typeof(Page), "Alert_NoCheck", "<script>alert('For Rejection, first you need to check the Checkbox');</script>", false);
        return;
    }

    // 第二步:处理所有勾选的行
    foreach (GridViewRow row in rptHotoIPDataInfo.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {
            CheckBox chkRow = row.FindControl("chkRow") as CheckBox;
            TextBox txtRemarks = row.FindControl("txtRemarks") as TextBox;
            Label lblID = row.FindControl("lbl_ID") as Label;

            if (chkRow != null && chkRow.Checked)
            {
                if (lblID == null || txtRemarks == null) continue;

                strID = lblID.Text;
                strRemarks = txtRemarks.Text;
                strCurrentUser = CurrentUserName;
                int intGroupID = CurrentUserGroupID;

                if (string.IsNullOrEmpty(strRemarks))
                {
                    // 用唯一key避免提示被覆盖
                    ScriptManager.RegisterStartupScript(this, typeof(Page), $"Alert_RemarkEmpty_{strID}", "<script>alert('Rejected Remarks cannot be blank');</script>", false);
                    continue; // 跳过当前行,继续处理其他勾选行
                }

                isUpdateRow = UpdateRejectInfo(strID, strRemarks, strCurrentUser, intGroupID, strCurrentUser);

                if (isUpdateRow)
                {
                    BindHotoIPNonIPSubmit();
                }
            }
        }
    }
}

额外优化建议

  • 移除Checkbox的AutoPostBack="true",无实时联动需求时会触发不必要的回发;
  • 按钮的CommandArgument='<%#Eval("SAP_ID") %>'无效(按钮不在GridView行内),可直接移除;
  • 替换原生alert为更友好的模态框提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:22:08