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

发布于 2024-09-15 22:51:37 字数 3554 浏览 5 评论 0原文

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

页脚包含一个带有 LinkBut​​ton 的 TemplateField,用于提供执行插入操作的回发。在 LinkBut​​ton 单击的处理程序中,对 GridView 绑定到的 ObjectDataSource 调用 Insert() 方法。 ObjectDataSource 的插入参数填充在其 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。同样,这工作正常,我可以毫无问题地添加、编辑和删除行。

当我使用此页面中的模式对话框将额外的行插入到用于填充 FooterRow 中的 DropDownLists 的表中时,问题就出现了。插入操作工作正常,模式对话框关闭,此时我使用 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

这个子 updateFuelEngineDropdowns() 是从 Page Load 事件中调用的。我第一次调用它时效果很好。由于某种原因,在调试器的后续运行中,我收到了 NullReferenceExceptions。深入研究调试对象查看器,很明显 GridView FooterRow 正在引用页脚上方不包含控件的行(至少在这个非编辑阶段)并且所以,相当合理地,给了我空引用。

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

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

有谁知道为什么会发生这种情况?

谢谢丹

I have a GridView and, using a fairly common method, I'm using a FooterRow and TemplateFields to provide the missing insert ability. So far so good.

The footer contains a TemplateField with a LinkButton to provide the postback that does the insertion. In the handler for the LinkButton's click, the Insert() method is called on the ObjectDataSource that the GridView is bound to. The ObjectDataSource's insert parameters are populated in the handler for its Inserting event. The code for all of this (abridged) looks like this:

Markup:

<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>

Code Behind:

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

Two of the fields in my FooterRow are DropDownLists that are populated from other tables. Again this works fine and I can add, edit and remove rows without problem.

The problem comes when I use a modal dialog from this page to insert extra rows into the tables used to populate the DropDownLists in the FooterRow. The insert operations work fine and the modal dialog closes and at this point I use a javascript postback (basically a call to __doPostBack()) so that my FooterRow DropDownLists can be updated. The code for this is:

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

This sub, updateFuelEngineDropdowns(), is called from the Page Load event. The first time I called it it worked fine. For some reason in subsequent runs through the debugger I'm getting NullReferenceExceptions. Digging into the debug object viewer it is apparent that the GridView FooterRow is referencing the row above the footer which contains no controls (at least not at this non-editing stage) and so, quite reasonably, gives my the Null reference.

The debug QuickView expressions I use are:
gvComplexRates.FooterRow.Controls(3)
DirectCast(gvComplexRates.FooterRow.Controls(3),System.Web.UI.WebControls.DataControlFieldCell).Controls(1)

The first of these shows a tag of td. Which makes sense. The second shows text of "10" which is the content for the row above the footer.

Does anybody know why this is happening?

Thanks Dan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你曾走过我的故事 2024-09-22 22:51:37

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

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

Where are you "providing the missing insert ability"?
You have to rebuild the footer-controls on every postback, the GridView.RowCreated-Event would be a good place.

Update:
You have to Databind your GridView after you inserted new rows into your Dropdowns' Tables.

魂ガ小子 2024-09-22 22:51:37

没错,这有点尴尬。我在最初的问题中撒了一个善意的谎言。通过遗漏而不是故意误导。事实上,我没有使用 GridView,而是它的子类,当数据源不包含数据时,它将显示行。这使得用户能够在表为空时插入新行。这个子类重写了 FooterRow 属性,令我羞愧的是,正是这个导致了错误。所以我在这里犯了两个错误:首先,我未能正确测试我的 GridView 子类;其次,我试图通过不在我包含的代码片段中显示它的使用来防止我认为对我的子类产生不必要的关注在问题中。我的不好。感谢蒂姆花时间尝试帮助我。

Right, this is a bit embarrassing. I gave a little white lie in the original question. By omission rather than a deliberate attempt to mislead. I am not, in fact, using a GridView but a subclass of it that will display rows when the datasource contains no data. This enables the user to insert new rows when the table is empty. This subclass overrides the FooterRow property and, to my shame, it was this that was getting things wrong. So I made two errors here: first I failed to test my GridView subclass properly and second I sought to prevent what I thought would be unnecessary attention on my subclass by not showing its use in the code snippets I included in the question. My bad. Thanks to Tim for taking the time to try and help me.

Dan

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文