代码之家  ›  专栏  ›  技术社区  ›  Dan Kendall

为什么我的gridview footerrow引用了错误的行?

  •  1
  • Dan Kendall  · 技术社区  · 15 年前

    我有一个 GridView 而且,使用一种相当常见的方法,我正在使用 FooterRow TemplateFields 提供缺失的插入功能。到现在为止,一直都还不错。

    页脚包含一个带有LinkButton的模板字段,用于提供执行插入操作的回发。在LinkButton单击的处理程序中,对GridView绑定到的对象数据源调用insert()方法。对象数据源的插入参数填充在其插入事件的处理程序中。所有这些代码(节略)如下:

    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>
    

    代码落后:

    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
    

    我的两个领域 脚行 DropDownLists 从其他表填充的。同样,这也很好,我可以毫无问题地添加、编辑和删除行。

    当我使用此页中的模式对话框向用于填充 下拉列表 脚行 . 插入操作工作正常,模式对话框关闭,此时我使用javascript回发(基本上是调用 __doPostBack() 让我的 脚行 下拉列表 可以更新。此代码是:

    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() 从页面加载事件调用。我第一次打电话的时候,效果很好。出于某种原因,在随后运行的调试器中 NullReferenceExceptions . 深入到调试对象查看器中,很明显 GRIDVIEW 脚行 正在引用页脚上方的行,该行不包含任何控件(至少在此非编辑阶段不包含),因此,非常合理地给出了空引用。

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

    第一个显示的是 td . 这是有道理的。第二个显示文本“10”,即页脚上方行的内容。

    有人知道这是为什么吗?

    谢谢丹

    2 回复  |  直到 15 年前
        1
  •  2
  •   Tim Schmelter    15 年前

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

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

        2
  •  0
  •   Dan Kendall    15 年前

    对,这有点尴尬。我在最初的问题上撒了一点善意的谎。通过疏忽而不是蓄意误导。事实上,我没有使用 GridView 但它的子类将在 datasource 不包含数据。这允许用户在表为空时插入新行。此子类重写 FooterRow 令我羞愧的是,正是这件事让事情变得错误。所以我在这里犯了两个错误:首先我没能测试我的 GRIDVIEW 正确地使用子类,其次,我试图通过在问题中包含的代码片段中不显示子类的用法来防止我认为对我的子类不必要的注意。我的错。感谢蒂姆抽出时间来帮助我。