FindControl cannot find the label control

Jamie picture Jamie · Feb 14, 2012 · Viewed 15.8k times · Source

I have a DataList inside a DataList that causes my page to lose the controls. The page works and there are no errors, but my label is never found! This is odd because the label shows on the aspx page, it just doesn't remove the 2 items that I want it to remove. When debugging, it skips over the If statement altogether:

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

I don't understand why it thinks the Label is Null because it is pulling information from the database and there are no null values.

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>

UPDATE: I changed the code somewhat, but now I get the error Object reference not set to an instance of an object. on Line 47

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>

UPDATE: Working code post!

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

This will only hide the text for "Systems", I have gone through each label in that particular question and each has hidden itself. This code does work on another page so I know that Self Directed is exactly how it is capitalized. I even copied and pasted from the database and it still wouldn't hide. Very stubborn.

Answer

Tim Schmelter picture Tim Schmelter · Feb 14, 2012

This should work:

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

Since the Label is in the inner DataList item that you're looping.

By the way, the same applies to you HiddenField hidPickID if that would be your next error ;-)

Edit;

I would recommend to handle the DataList2.ItemDataBound event as well. Then your code is less error-prone and clearer and you don't need to loop all items in DataList1.ItemDataBound.

You need to call DataList2.DataBind before in DataList1.ItemDataBound.

Edit2:

You can cast DataList2.NamingContainer to DataListItem to get the parent-item, then you can find your HiddenField(in DateList2.ItemDataBound):

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

But i would recommend to use the DataSource instead, for example(in DateList2.ItemDataBound):

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

(if it's stored in the DataRow what it should)