Почему FindControl не может найти кнопку в нижнем колонтитуле моего ретранслятора?
Я использую событие OnItemDataBound, чтобы попытаться активировать отключенную кнопку в ретрансляторе. Проще говоря, если событие срабатывает, я знаю, что в ретрансляторе есть элементы, и поэтому хочу включить кнопку. Где я застрял, так это на приведении кнопки в функцию, чтобы я мог ее включить. Соответствующая часть кода ретранслятора приводится ниже:
<asp:Repeater ID="RptEnterHours" runat="server" DataSourceID="SQL_EmployeeGetTimesheet" ClientIDMode="Predictable" OnItemDataBound="RptEnterHours_Bound">
'.....Irrelevant code.....
<FooterTemplate>
<asp:Button Enabled="false" ID="SubmitTimesheets" Text="Submit All Timesheets" OnClick="processTimesheetEntry" runat="server" OnClientClick="checkValues();" />
</FooterTemplate>
</asp:Repeater>
Вот мой код:
Sub RptEnterHours_Bound(Sender As Object, e As RepeaterItemEventArgs)
'Exposes the Submit All Timesheets button if timesheets are available.
If (e.Item.ItemType = ListItemType.Item) Or _
(e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim sButton As Button = TryCast(Me.FindControl("SubmitTimesheets"), Button)
sButton.Enabled = True
End If
End Sub
Эта и все другие попытки дали страшную " ссылку на объект, не заданную экземпляр сообщения объекта". Может ли кто-нибудь сказать мне, что я делаю неправильно и почему мой код не находит кнопку?
6 ответов:
Пожалуйста, попробуйте это, я уверен, что это поможет вам.
If e.Item.ItemType = ListItemType.Footer Then Dim btn as new button btn = CType(e.Item.FindControl("SubmitTimesheets"), Button) btn.enabled = true End If
Вы ограничиваете его поиском внутри элемента и чередованием шаблонов элементов.
Измените это:
If (e.Item.ItemType = ListItemType.Item) Or _ (e.Item.ItemType = ListItemType.AlternatingItem) Then
Кому:
If (e.Item.ItemType = ListItemType.Footer) Then
Вы хотите проверить для e.Item.ItemType = ListItemType.Нижняя сноска. Item и AlternatingItem используются для фактических записей данных, а не для нижнего колонтитула. Таким образом, кнопка действительно не существует для элементов и AlternatingItems.
Затем вы захотите добавить тест на наличие RptEnterHours.Объект DataSource имеет записи. Для этого вам нужно будет разыграть RptEnterHours.Источник данных для любого типа источника данных.
Итак, в основном что-то вроде этого. Вы, очевидно, нужно изменить его, чтобы он соответствовал вашему коду:
Sub RptEnterHours_Bound(Sender As Object, e As RepeaterItemEventArgs) 'Exposes the Submit All Timesheets button if timesheets are available. If (e.Item.ItemType = ListItemType.Footer) Then Dim sButton As Button = TryCast(Me.FindControl("SubmitTimesheets"), Button) Dim myDataSource = CType(RptEnterHours.DataSource, MyDataSourceType) sButton.Enabled = (myDataSource.Count > 0) End If End Sub
Прошло немного времени с тех пор, как я работал с веб-формами, но я считаю, что проблема состоит в двух аспектах.
Если тип элемента-Item или AlternatingItem, то вы знаете, что у вас есть данные в ретрансляторе. В этих случаях вы можете установить флаг уровня экземпляра, чтобы указать, что у вас есть элементы.
Затем, когда тип элемента-нижний колонтитул, и у вас есть элементы, которые вы хотите включить, чтобы нажать кнопку. Способ сделать это упоминается в неприемлемом ответе на вопрос, связанный с @ codingkiwi.com, но я ... поверьте, проблема заключается в контексте, в котором вы вызываете FindControl. Ты зовешь меня.FindControl, который будет искать дочерние элементы уровня 1 страницы (или пользовательский элемент управления, или элемент управления, или то, на что я ссылаюсь). Вы хотите искать дочерние элементы управления фактического элемента repeater, который в данном случае является нижним колонтитулом. Таким образом, поиск становится e.Item.FindControl.
Следует отметить, что, вероятно, существуют более элегантные способы определить, имеет ли управление ретранслятором элементы. Возможно, все, что вам нужно проверить в событии OnDataBound-это элемент нижнего колонтитула, а затем искать что-то вроде: (мой VB тоже может быть немного ржавым)
If (Me.RptEnterHours.Items IsNot Null AndAlso Me.RptEnterHours.Items.Any()) Then
Не уверен, почему он просто не включен в первую очередь, но это будет работать, так как он будет срабатывать для нижнего колонтитула после типа Item / AlternatingItem:
Private m_bolEnableButton As Boolean = False Sub RptEnterHours_Bound(Sender As Object, e As RepeaterItemEventArgs) 'Exposes the Submit All Timesheets button if timesheets are available. If (e.Item.ItemType = ListItemType.Item) Or _ (e.Item.ItemType = ListItemType.AlternatingItem) Then '"if the event is triggered, I know there are items in the repeater and therefore want to enable the button" m_bolEnableButton = True End If If e.Item.ItemType = ListItemType.Footer Then If m_bolEnableButton Then Dim sButton As Button = TryCast(e.Item.FindControl("SubmitTimesheets"), Button) sButton.Enabled = True End If m_bolEnableButton = False End If End Sub
Причина, по которой вы получаете исключение Object null reference, заключается в том, что вы зациклены на приведении, которое не вызывает проблемы. Как правило, вы можете безопасно приводить результаты FindControl неявно. То, что вам нужно явно проверить, - это нулевая ссылка после того, как результаты FindControl будут захвачены.
Кроме того, вы должны искать
Наконец, функция FindControl () не является рекурсивной. Он находит элементы управления только в именовании верхнего уровня контейнер. В большинстве элементов управления databound каждая строка представляет свой собственный контейнер имен , поэтому вы должны найти элемент управления в строке, которую хотите найти. Когда вы используетеListItemType.Footer
, чтобы вы могли ссылаться на строку нижнего колонтитула.Me
, он ссылается на страницу. Вместо этого вы должны использовать e.Пункт.FindControl().Код:
Dim bRecordsFound as Boolean = False Sub RptEnterHours_Bound(Sender As Object, e As RepeaterItemEventArgs) If (e.Item.ItemType = ListItemType.Item) Or _ (e.Item.ItemType = ListItemType.AlternatingItem) Then bRecordsFound = True End If If (e.Item.ItemType = ListItemType.Footer) And (bRecordsFound) Then Dim sButton As Button = e.Item.FindControl("SubmitTimesheets") If sButton IsNot Nothing Then sButton.Visible = True End If End If End Sub