为什么我的GridView FooterRow引用了错误的行?

时间:2010-08-26 10:25:45

标签: asp.net vb.net gridview nullreferenceexception footer

我有GridView并且使用相当常见的方法,我使用FooterRowTemplateFields来提供缺少的插入功能。到目前为止一切都很好。

页脚包含一个带有LinkBut​​ton的TemplateField,用于提供插入的回发。在LinkBut​​ton单击的处理程序中,在GridView绑定的ObjectDataSource上调用Insert()方法。 ObjectDataSource的insert参数填充在其Inserting事件的处理程序中。所有这些(删节)的代码如下所示:

标记:

<asp:GridView ID="gvComplexRates" runat="server" AutoGenerateColumns="False" 
                DataKeyNames="id" DataSourceID="odsComplexMileageRates" 
                EnableModelValidation="True" ShowFooter="True">
                <Columns>
                   <asp:TemplateField ShowHeader="False">
                        :
                        :
                        <FooterTemplate>
                            <asp:LinkButton ID="addLinkButton" runat="server" CausesValidation="false"
                                CommandName="Insert" Text="Add"></asp:LinkButton>
                        </FooterTemplate>
                    </asp:TemplateField>
                    :
                    :
</asp:GridView>

代码背后:

Private Sub gvComplexRates_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvComplexRates.RowCommand

    Select Case e.CommandName
        Case "Insert"
            odsComplexMileageRates.Insert()
    End Select
End Sub

Private Sub odsComplexMileageRates_Inserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceMethodEventArgs) Handles odsComplexMileageRates.Inserting
    Dim fuelTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
    Dim engineTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
    Dim rateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbRateInsert")
    Dim vatRateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbVatRateInsert")

    e.InputParameters("expense_type_id") = ddExpenseTypeSelect.SelectedValue
    e.InputParameters("fuel_type_id") = fuelTypeDropDown.SelectedValue
    e.InputParameters("engine_type_id") = engineTypeDropDown.SelectedValue
    e.InputParameters("rate") = rateTextBox.Text
    e.InputParameters("vat_rate") = vatRateTextBox.Text
End Sub

FooterRow中的两个字段是从其他表填充的DropDownLists。再次,这工作正常,我可以毫无问题地添加,编辑和删除行。

当我使用此页面中的模态对话框将额外的行插入用于填充DropDownLists中的FooterRow的表格时,问题就出现了。插入操作正常,模式对话框关闭,此时我使用javascript回发(基本上是对__doPostBack()的调用),以便我的FooterRow DropDownLists可以更新。代码是:

Protected Sub updateFuelEngineDropdowns()
    odsFuelTypes.Select()
    odsEngineTypes.Select()
    Dim dropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
    dropDown.DataBind()
    dropDown = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
    dropDown.DataBind()
End Sub

从Page Load事件中调用此子updateFuelEngineDropdowns()。我第一次打电话给它工作正常。出于某种原因,在后续的调试程序中,我得到了NullReferenceExceptions。深入研究调试对象查看器显然,GridView FooterRow引用了页脚上方不包含任何控件的行(至少不在此非编辑阶段),所以非常合理地给出了我的空参考。

我使用的调试QuickView表达式是:
gvComplexRates.FooterRow.Controls(3) DirectCast(gvComplexRates.FooterRow.Controls(3),System.Web.UI.WebControls.DataControlFieldCell).Controls(1)

其中第一个显示td的标记。这是有道理的。第二个显示“10”的文本,它是页脚上方行的内容。

有人知道为什么会这样吗?

谢谢Dan

2 个答案:

答案 0 :(得分:2)

你在哪里“提供缺失的插入能力”? 您必须在每次回发时重建页脚控件,GridView.RowCreated-Event将是一个好地方。

更新: 在向下拉列表中插入新行后,必须对GridView进行数据绑定。

答案 1 :(得分:0)

是的,这有点令人尴尬。我在原来的问题上给了一点白色谎言。通过省略而不是故意误导。实际上,我不是使用GridView,而是使用它的子类,当datasource不包含任何数据时,它将显示行。这使用户可以在表为空时插入新行。这个子类重写了FooterRow属性,令我感到羞耻的是,这是错误的。所以我在这里犯了两个错误:首先我没有正确地测试我的GridView子类,然后我试图通过不在代码片段中显示它在我的子类中的不必要的注意来防止我在问题中包含的内容。我的错。感谢蒂姆花时间尝试帮助我。