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

如何根据条件勾选ASP.NET GridView中的复选框?

解决GridView复选框勾选时的“未将对象引用设置到对象实例”错误

问题根源

  1. 遍历GridView行时未过滤非数据行(如表头行),这类行不存在目标控件,FindControl会返回null,后续赋值触发空引用异常
  2. 转换控件后未做null判断,直接访问Checked属性
  3. 嵌套循环匹配ID效率低,且未处理Label控件找不到或文本为空的情况

修正方案一:优化Page_Load中的遍历逻辑

修改后台代码,增加行类型判断、控件null校验,并优化ID匹配效率:

public localhost.WebService1 w = new localhost.WebService1();
public localhost.User u = new localhost.User();

if (!IsPostBack)
{
    this.GridView.DataSource = w.SelectListOfIds();
    this.GridView.DataBind();
    
    // 将ID数组转为HashSet,提升匹配效率
    HashSet<int> userIds = new HashSet<int>(w.SelectListOfIDSOfUser(u.UserId));
    
    foreach (GridViewRow row in GridView.Rows)
    {
        // 仅处理数据行
        if (row.RowType == DataControlRowType.DataRow)
        {
            Label idLabel = row.FindControl("Id") as Label;
            if (idLabel != null && !string.IsNullOrEmpty(idLabel.Text))
            {
                if (int.TryParse(idLabel.Text, out int cId))
                {
                    if (userIds.Contains(cId))
                    {
                        CheckBox checkbox = row.FindControl("CheckBox1") as CheckBox;
                        // 校验控件存在后再赋值
                        if (checkbox != null)
                        {
                            checkbox.Checked = true;
                        }
                    }
                }
            }
        }
    }
}

关键优化点:

  • 用HashSet<int>存储ID列表,将嵌套循环的O(n*m)复杂度降为O(n)
  • 增加row.RowType == DataControlRowType.DataRow判断,跳过非数据行
  • 用as转换控件后先判断null,避免空引用
  • 用int.TryParse替代Convert.ToInt32,避免格式错误抛出异常

修正方案二:利用RowDataBound事件(更符合WebForm规范)

通过GridView的RowDataBound事件逐行处理,直接从绑定数据中获取ID,无需依赖Label控件:

后台代码

public localhost.WebService1 w = new localhost.WebService1();
public localhost.User u = new localhost.User();
private HashSet<int> _userIds;

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        _userIds = new HashSet<int>(w.SelectListOfIDSOfUser(u.UserId));
        this.GridView.DataSource = w.SelectListOfIds();
        this.GridView.DataBind();
    }
}

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // 直接从绑定的数据项中获取ID
        int rowId = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "id"));
        CheckBox checkbox = e.Row.FindControl("CheckBox1") as CheckBox;
        if (checkbox != null)
        {
            checkbox.Checked = _userIds.Contains(rowId);
        }
    }
}

前端GridView代码(添加事件绑定)

<asp:GridView ID="GridView" showheader=false runat="server" BorderWidth="1px" CellPadding="4" 
    ForeColor="Black" GridLines="Horizontal" AutoGenerateColumns="false" AllowPaging="true" 
    CssClass="wrapper5" OnRowDataBound="GridView_RowDataBound">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:CheckBox ID="CheckBox1" runat="server"/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Label ID="Id" Text='<%# Eval("id") %>' runat="server"></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

该方案优势:逻辑更清晰,直接从绑定数据源取ID,减少控件查找开销和潜在错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:05:39