У меня есть GridView
и, используя довольно распространенный метод, я использую FooterRow
и TemplateFields
, чтобы обеспечить отсутствующую способность вставки. Пока все хорошо.
Нижний колонтитул содержит TemplateField с LinkButton для обеспечения обратной передачи, которая выполняет вставку. В обработчике для клика LinkButton, метод Insert () вызывается для ObjectDataSource, к которому привязан GridView. Параметры вставки ObjectDataSource заполняются в обработчике для события вставки. Код для всего этого (сокращенно) выглядит следующим образом:
Разметка:
<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. Элементы управления (3)
DirectCast (gvComplexRates.FooterRow.Controls (3), System.Web.UI.WebControls.DataControlFieldCell) .Controls (1)
В первом из них показан тег td
. Что имеет смысл. Второй показывает текст «10», который является содержанием строки над нижним колонтитулом.
Кто-нибудь знает, почему это происходит?
Спасибо, Дэн
Да, это немного смущает. Я дал небольшую белую ложь в исходном вопросе. Упущением, а не преднамеренной попыткой ввести в заблуждение. На самом деле я использую не GridView
, а его подкласс, который будет отображать строки, когда источник данных
не содержит данных. Это позволяет пользователю вставлять новые строки, когда таблица пуста. Этот подкласс переопределяет свойство FooterRow
и, к моему стыду, именно это неправильно. Итак, я сделал здесь две ошибки: во-первых, я не смог должным образом протестировать свой подкласс GridView
, а во-вторых, я попытался предотвратить то, что, как я думал, будет ненужным вниманием к моему подклассу, не показывая его использование во фрагментах кода, которые я включил в вопрос. Виноват. Спасибо Тиму, что нашел время, чтобы попытаться помочь мне.
Дэн
Где вы «предоставляете отсутствующую возможность вставки»? Вы должны перестраивать элементы управления нижнего колонтитула при каждой обратной передаче, GridView.RowCreated-Event будет хорошим местом.
Обновление: Вы должны привязать свой GridView к данным после того, как вставили новые строки в свои таблицы раскрывающихся списков.