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

ASPxGridView多页场景下ASPxCheckBox引发对象引用未设置实例错误

ASPxGridView分页下遍历模板控件触发空引用错误的原因分析

问题场景

  • 使用DevExpress ASPxGridView控件,在列模板中嵌入ASPxCheckBox
  • 分页大小设置为20行,当数据总条数超过20条(存在多页)时,点击btnTransferAsset按钮执行遍历逻辑,循环到第21行时出现Object reference not set to an instance of an object错误

页面标记代码

<dx:ASPxGridView ID="grdAsset" runat="server" Width="100%" AutoGenerateColumns="true" Caption="Assets List" KeyFieldName="id" DataSourceID="getAssets">
    <Columns>
        <dx:GridViewDataColumn Caption="" FieldName="id" VisibleIndex="0" Visible="false" ReadOnly="true" />
        <dx:GridViewDataButtonEditColumn Caption="#" VisibleIndex="1" Width="50px">
            <DataItemTemplate>
                <dx:ASPxCheckBox ID="chkID" runat="server" />
            </DataItemTemplate>
        </dx:GridViewDataButtonEditColumn>
        <dx:GridViewDataColumn Caption="" FieldName="asset_id" VisibleIndex="2" />
        <dx:GridViewDataColumn Caption="Asset Category" FieldName="category_name" VisibleIndex="3" />
        <dx:GridViewDataColumn Caption="Asset Brand Name" FieldName="brand_name" VisibleIndex="4" />
        'others Datacolumn.....
    </Columns>
    <SettingsBehavior AllowSelectByRowClick="true" ColumnResizeMode="Control" />
    <SettingsPager Position="Bottom" PageSize="20">
        <PageSizeItemSettings Items="10, 20, 50, 100, 200, 500" ShowAllItem="True" Visible="True" />
    </SettingsPager>
    <Settings ShowFilterRow="true" ShowFooter="true" />
    <SettingsDataSecurity AllowDelete="False" AllowEdit="False" AllowInsert="False" />
    <Settings GridLines="Horizontal" />
    <Styles>
        <AlternatingRow Enabled="True" />
    </Styles>
</dx:ASPxGridView>
<asp:ObjectDataSource ID="getAssets" runat="server" TypeName="Asset" SelectMethod="selectAsset">
    <SelectParameters>
          'the parameters...
    </SelectParameters>
</asp:ObjectDataSource>

<br/>

<dx:ASPxButton ID="btnTransferAsset" runat="server" Text="Transfer Assets" Font-Bold="true" Visible="false" OnClick="btnTransferAsset_Click" />

后台代码

Private Sub btnTransferAsset_Click (sender As Object, e As EventArgs)
            Dim dt As New DataTable
            dt.Columns.AddRange(New DataColumn(2) {New DataColumn("id"), New DataColumn("asset_id"), New DataColumn("category_name")})
            For rowIndex As Integer = 0 To grdAsset.VisibleRowCount - 1
                Dim column As GridViewDataButtonEditColumn = CType(grdAsset.Columns(1), GridViewDataButtonEditColumn)
                Dim cb As ASPxCheckBox = CType(grdAsset.FindRowCellTemplateControl(rowIndex, column, "chkID"), ASPxCheckBox)

                If cb.Checked Then 'got error here, at the loop 21 times, it shows "Object reference not set to an instance of an object." 
                    Dim id As Integer = CType(grdAsset.GetRowValues(rowIndex, New String() {"id"}), Integer)
                    Dim asset_id As String = CType(grdAsset.GetRowValues(rowIndex, New String() {"asset_id"}), String)
                    Dim category_name As String = CType(grdAsset.GetRowValues(rowIndex, New String() {"category_name"}), String)
                    dt.Rows.Add(id, asset_id, category_name)
                End If
            Next
            'my others code...
End Sub

错误原因

核心原因是ASPxGridView在分页模式下,仅当前页的行对应的模板控件会被渲染到服务器端控件树中,非当前页的行并没有生成对应的ASPxCheckBox控件实例。

代码中grdAsset.VisibleRowCount返回的是所有数据的总行数(比如21条),但循环到第21行(对应第二页的第一行)时,FindRowCellTemplateControl找不到该页面对应的chkID控件,返回Nothing,此时直接访问cb.Checked就会触发空引用错误。

另外需要注意:grdAsset.GetRowValues可以获取到所有行的数据,是因为这个方法直接从GridView绑定的数据源(或控件内部缓存的全量数据)中读取,不需要依赖页面上已渲染的控件,所以即使行不在当前页也能正常取值,但模板控件只存在于当前页。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:00:59