【问题标题】:FindControl cannot find the label controlFindControl 找不到标签控件
【发布时间】:2012-02-14 16:12:49
【问题描述】:

我在 DataList 中有一个 DataList,导致我的页面丢失了控件。该页面有效并且没有错误,但从未找到我的标签!这很奇怪,因为标签显示在 aspx 页面上,它只是没有删除我希望它删除的 2 个项目。调试时,它会完全跳过 If 语句:

If lbl IsNot Nothing Then
    If lbl.Text = "Self Directed" Or lbl.Text = "Systems" Then
        lbl.Visible = False
    End If
End If

我不明白为什么它认为 Label 为 Null,因为它正在从数据库中提取信息并且没有 null 值。

Protected Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemDataBound
    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        'Find the controls that are inside the DataList
        Dim anstype As HiddenField = e.Item.FindControl("HiddenField1")
        Dim questionid As HiddenField = e.Item.FindControl("HiddenField2")
        Dim rbl As RadioButtonList = e.Item.FindControl("RadioButtonList1")
        Dim cbl As CheckBoxList = e.Item.FindControl("CheckBoxList1")
        Dim txt As TextBox = e.Item.FindControl("TextBox1")
        Dim ds As DataSet = GetDataSet(questionid.Value)
        Select Case anstype.Value
            'if anstype is 's' then show a radio button list
            Case "S"
                rbl.Visible = True
                cbl.Visible = False
                txt.Visible = False
                rbl.DataSource = ds
                rbl.DataTextField = "Choice"
                rbl.DataValueField = "ChoiceID"
                rbl.DataBind()
                'if anstype is 'm' then show a checkbox list
            Case "M"
                rbl.Visible = False
                cbl.Visible = True
                txt.Visible = False
                cbl.DataSource = ds
                cbl.DataTextField = "Choice"
                cbl.DataValueField = "ChoiceID"
                cbl.DataBind()
                'if anstype is 't' then show a textbox
            Case "T"
                rbl.Visible = False
                cbl.Visible = False
                txt.Visible = True
        End Select
        Dim dl2 As DataList = CType(e.Item.FindControl("DataList2"), DataList)
        Dim hidden2 As HiddenField = DirectCast(e.Item.FindControl("HiddenField2"), HiddenField)
        Dim QID As Integer = Int32.Parse(hidden2.Value)
        If QID = 33 Then
            For Each li As DataListItem In dl2.Items
                Dim lbl As Label = DirectCast(e.Item.FindControl("Label3"), Label)
                If lbl IsNot Nothing Then
                    If lbl.Text = "Self Directed" Or lbl.Text = "Systems" Then
                        lbl.Visible = False
                    End If
                End If
            Next
        End If
    End If
End Sub


<asp:DataList ID="DataList1" runat="server" DataSourceID="SqlDataSource1" Width="100%" CellPadding="4" ForeColor="#333333">
<ItemTemplate>

<asp:HiddenField ID="HiddenField2" runat="server" Value='<%# Eval("QuestionID") %>'>
</asp:HiddenField>
<asp:Label ID="lblQuesNum" runat="server" Font-Bold="True" Text='<%# Eval("QuestionNum") %>'>
</asp:Label>
<strong>)</strong>
<asp:Label ID="Label2" runat="server" Font-Bold="True" Text='<%# Eval("Question") %>'>
</asp:Label>
<asp:HiddenField ID="hiddenPicklistID" runat="server"  Value='<%# Eval("PicklistID") %>'>
</asp:HiddenField>
<asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Eval("AnswerType") %>'>  
</asp:HiddenField>

<asp:DataList ID="DataList2" runat="server" DataSourceID="dsPicklist">
<ItemTemplate>
    <asp:HiddenField ID="hidPickID" runat="server" value='<%# Eval("PICKLISTID") %>'>  
    </asp:HiddenField>
    <asp:Label ID="Label3" runat="server" Text='<%# Eval("TEXT") %>'></asp:Label> 
</ItemTemplate>
</asp:DataList>

</asp:DataList>

更新: 我稍微更改了代码,但现在我在第 47 行收到错误 Object reference not set to an instance of an object.

Line 45:             Dim dl2 As DataList = CType(e.Item.FindControl("DataList2"), DataList)
Line 46:             Dim hidden2 As HiddenField = DirectCast(e.Item.FindControl("HiddenField2"), HiddenField)
Line 47:             Dim QID As Integer = Int32.Parse(hidden2.Value)
Line 48:             If QID = 33 Then
Line 49:                 For Each li As DataListItem In dl2.Items



Protected Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemDataBound
    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        'Find the controls that are inside the DataList
        Dim anstype As HiddenField = e.Item.FindControl("HiddenField1")
        Dim questionid As HiddenField = e.Item.FindControl("HiddenField2")
        Dim rbl As RadioButtonList = e.Item.FindControl("RadioButtonList1")
        Dim cbl As CheckBoxList = e.Item.FindControl("CheckBoxList1")
        Dim txt As TextBox = e.Item.FindControl("TextBox1")
        Dim ds As DataSet = GetDataSet(questionid.Value)
        Dim dl2 As DataList = e.Item.FindControl("DataList2")
        dl2.DataBind()
        Select Case anstype.Value
..... the rest of this code is the same as above until Case "T"....


Protected Sub DataList2_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs)
    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        Dim dl2 As DataList = CType(e.Item.FindControl("DataList2"), DataList)
        Dim hidden2 As HiddenField = DirectCast(e.Item.FindControl("HiddenField2"), HiddenField)
        Dim QID As Integer = Int32.Parse(hidden2.Value)
        If QID = 33 Then
            For Each li As DataListItem In dl2.Items
                Dim lbl As Label = DirectCast(e.Item.FindControl("Label3"), Label)
                If lbl IsNot Nothing Then
                    If lbl.Text = "Self Directed" Or lbl.Text = "Systems" Then
                        lbl.Visible = False
                    End If
                End If
            Next
        End If
    End If
End Sub

<asp:DataList ID="DataList2" runat="server" DataSourceID="dsPicklist" OnItemDataBound="DataList2_ItemDataBound">
<ItemTemplate>
    <asp:HiddenField ID="hidPickID" runat="server" value='<%# Eval("PICKLISTID") %>'></asp:HiddenField>
    <asp:Label ID="Label3" runat="server" Text='<%# Eval("TEXT") %>'></asp:Label> 
</ItemTemplate>
</asp:DataList>

更新:工作代码发布!

Protected Sub DataList2_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs)
    If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        Dim DataList2 = DirectCast(sender, DataList)
        Dim ParentItem = DirectCast(DataList2.NamingContainer, DataListItem)
        Dim HiddenField2 = DirectCast(ParentItem.FindControl("HiddenField2"), HiddenField)
        Dim QID As Integer = Int32.Parse(HiddenField2.Value)
        If QID = 33 Then
            For Each li As DataListItem In DataList2.Items
                Dim lbl As Label = DirectCast(e.Item.FindControl("Label3"), Label)
                If lbl IsNot Nothing Then
                    If lbl.Text = "Self Directed" Or lbl.Text = "Systems" Then
                        lbl.Visible = False
                    End If
                End If
            Next
        End If
    End If
End Sub

这只会隐藏“系统”的文本,我已经浏览了该特定问题中的每个标签,并且每个标签都隐藏了自己。此代码在另一个页面上确实有效,因此我知道 Self Directed 正是它的大写方式。我什至从数据库中复制和粘贴,它仍然不会隐藏。很固执。

【问题讨论】:

  • 你在哪一行得到错误?
  • 在原始帖子中添加了错误消息...

标签: vb.net datalist findcontrol


【解决方案1】:

这应该可行:

Dim lbl As Label = DirectCast(li.FindControl("Label3"), Label)

由于标签位于您正在循环的内部 DataList 项目中。

顺便说一句,如果那是你的下一个错误,这同样适用于你 HiddenField hidPickID ;-)

编辑

我建议也处理DataList2.ItemDataBound 事件。这样您的代码就不容易出错且更清晰,并且您不需要循环 DataList1.ItemDataBound 中的所有项目。

您需要在DataList1.ItemDataBound之前致电DataList2.DataBind

编辑2

您可以将DataList2.NamingContainer 转换为DataListItem 以获取父项,然后您可以找到您的HiddenField(在DateList2.ItemDataBound):

Dim DataList2 = DirectCast(sender, DataList)
Dim ParentItem = DirectCast(DataList2.NamingContainer), DataListItem)
Dim HiddenField2 = DirectCast(ParentItem.FindControl("HiddenField2"),HiddenField)

但我建议改用 DataSource,例如(在 DateList2.ItemDataBound 中):

Dim rowView As DataRowView = CType(e.Item.DataItem, DataRowView)
Dim QID = DirectCast(rowView("QID"), Int32)

(如果它存储在DataRow中应该是什么)

【讨论】:

  • 我改变了它,现在它通过了 If 语句。不过,它仍然没有隐藏这 2 个标签项。而且我之前尝试过处理 DataList2 ItemDataBound ,但它甚至没有命中它。这就是为什么我将该代码与 DataList1 一起放入......它将以这种方式运行。
  • @jlg:那么您错过了在 DataList1.ItemDataBound 中调用 DataList2.DataBind(请参阅我的编辑)。即使您的代码现在可以工作,我仍然建议使用 DataList2.ItemDataBound 将两者分开。您仍然可以在那里获得对 DataList1-Item 的引用。
  • 我将Dim dl2 As DataList = DataList1.FindControl("DataList2") dl2.DataBind() 放在If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then 行之前,我收到错误Object reference not set to an instance of an object. 我将同样的2 行放在If e.Item 行的正下方,而DataList2_ItemDataBound 仍然没有运行.你知道为什么它在我的页面上找不到任何东西吗?
  • 您需要确保您当前的项目是ListItemType.ItemListItemType.AlternatingItem。您是否真的将ItemdataBound 处理程序添加到DataList2(在aspx 或代码隐藏中)?尝试在绑定之前设置 DataSource。 dsPicklist 是什么?
  • @jlg: ...最后但同样重要的是:我没有看到您在 DataList2 上为此事件添加了处理程序。将此添加到您的 aspx:&lt;asp:DataList ID="DataList2" OnItemDataBound="DataList2_ItemDataBound" runat="server" DataSourceID="dsPicklist"&gt;
【解决方案2】:

尝试 li.FindControl("Label3") 插入 e.Item.FindControl("Label3")

【讨论】:

    猜你喜欢
    • 2012-08-06
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多