Почему мой GridView FooterRow ссылается на неправильную строку? - PullRequest
1 голос
/ 26 августа 2010

У меня есть GridView, и, используя довольно распространенный метод, я использую FooterRow и TemplateFields, чтобы обеспечить возможность отсутствующей вставки. Пока все хорошо.

Нижний колонтитул содержит TemplateField с LinkButton для обеспечения обратной передачи, которая выполняет вставку. В обработчике для щелчка LinkButton вызывается метод Insert () для ObjectDataSource, с которым связан GridView. Параметры вставки ObjectDataSource заполняются в обработчике для события вставки. Код для всего этого (сокращенно) выглядит так:

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

Два поля в моем 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

Этот саб, updateFuelEngineDropdowns(), вызывается из события загрузки страницы. Первый раз, когда я назвал это, он работал нормально. По некоторым причинам в последующих прогонах через отладчик я получаю NullReferenceExceptions. Если заглянуть в просмотрщик объектов отладки, то очевидно, что GridView FooterRow ссылается на строку над нижним колонтитулом, которая не содержит элементов управления (по крайней мере, на этом этапе без редактирования), и поэтому вполне разумно дает ссылку на Null .

Используемые мной выражения отладки QuickView:
gvComplexRates.FooterRow.Controls(3) DirectCast(gvComplexRates.FooterRow.Controls(3),System.Web.UI.WebControls.DataControlFieldCell).Controls(1)

Первый из них показывает тег td. Что имеет смысл. Второй показывает текст «10», который является содержанием строки над нижним колонтитулом.

Кто-нибудь знает, почему это происходит?

Спасибо, Дэн

Ответы [ 2 ]

2 голосов
/ 26 августа 2010

Где вы «предоставляете возможность отсутствующей вставки»?Вы должны перестраивать элементы нижнего колонтитула на каждой обратной передаче, GridView.RowCreated-Event было бы хорошим местом.

Обновление: вам нужно связать данные с вашим GridView после вставки новых строк вТаблицы ваших выпадающих.

0 голосов
/ 26 августа 2010

Да, это немного неловко.Я дал немного белой лжи в оригинальном вопросе.Упущением, а не преднамеренной попыткой ввести в заблуждение.На самом деле я не использую GridView, а его подкласс, который будет отображать строки, когда datasource не содержит данных.Это позволяет пользователю вставлять новые строки, когда таблица пуста.Этот подкласс переопределяет свойство FooterRow, и, к моему стыду, именно это неправильно.Поэтому я допустил две ошибки: во-первых, мне не удалось должным образом протестировать мой подкласс GridView, а во-вторых, я пытался предотвратить то, что, по моему мнению, было бы ненужным вниманием для моего подкласса, не показывая его использование в фрагментах кода, которые я включил в вопрос.Виноват.Спасибо Тиму, что нашли время, чтобы попытаться помочь мне.

Дан

...