为什么FindControl找不到我的中继器页脚中的按钮?

时间:2012-08-22 19:57:53

标签: asp.net vb.net repeater

我正在使用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();" />&nbsp;
     </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 个答案:

答案 0 :(得分:3)

请尝试这个我相信它会对你有帮助。

    If e.Item.ItemType = ListItemType.Footer Then
        Dim btn as new button
        btn = CType(e.Item.FindControl("SubmitTimesheets"), Button)
        btn.enabled = true
    End If

答案 1 :(得分:0)

您将其限制为在项目内查看和交替项目模板。

改变这个:

If (e.Item.ItemType = ListItemType.Item) Or _ 
        (e.Item.ItemType = ListItemType.AlternatingItem) Then 

要:

If (e.Item.ItemType = ListItemType.Footer) Then 

答案 2 :(得分:0)

您想要测试e.Item.ItemType = ListItemType.Footer。 Item和AlternatingItem用于实际数据记录,而不是页脚。因此,Items和AlternatingItems确实不存在按钮。

然后,您将要添加一个测试,以确定RptEnterHours.DataSource对象是否有记录。为此,您需要将RptEnterHours.DataSource转换为数据源的任何类型。

所以,基本上是这样的。您显然需要更改它以适合您的代码:

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

答案 3 :(得分:0)

自从我使用网络表单以来已经有一段时间了,但我相信这个问题有两个方面。

当项目类型为Item或AlternatingItem时,您知道转发器中有数据。在这些情况下,您可以设置实例级别标志以指示您有项目。

然后,当项目类型为页脚并且您有要启用按钮的项目时。在@ codingkiwi.com链接的问题的一个不可接受的答案中提到了这样做的方法,但我相信问题是你调用FindControl的上下文。您正在调用Me.FindControl,它将搜索页面的1级子级(或用户控件,或控件,或者我是引用的任何内容)。您希望搜索实际转发器元素的子控件,在本例中为子页脚。所以搜索变成了e.Item.FindControl。

应该注意的是,可能有更优雅的方法来检测转发器控件是否具有元素。也许您需要在OnDataBound事件中检查的是页脚项,然后寻找类似的东西:(我的VB也可能有点生锈)

If (Me.RptEnterHours.Items IsNot Null AndAlso Me.RptEnterHours.Items.Any()) Then

答案 4 :(得分:0)

不确定为什么它首先没有启用,但是这会起作用,因为它会在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

答案 5 :(得分:0)

您获得Object null引用异常的原因是因为您注意了强制转换,这不会导致问题。您通常可以隐式地安全地转换FindControl的结果。在捕获FindControl结果之后,您需要显式检查的是空引用。

此外,您应该寻找ListItemType.Footer,以便引用页脚行。

最后,FindControl()不是递归的。它只在顶级命名容器中找到控件。在大多数数据绑定控件中,每行代表自己的命名容器,因此您必须在要搜索的行中使用FindControl 。使用Me时,它指的是页面。您应该使用e.Item.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