Search code examples
c#.netasp.netfindcontrol

C#, FindControl


I'm sorry, but I can't understand why this doesn't work. After compile, I receive a "Null reference exception". Please help.

public partial class labs_test : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (TextBox1.Text != "")
        {
            Label Label1 = (Label)Master.FindControl("Label1");
            Label1.Text = "<b>The text you entered was: " + TextBox1.Text + ".</b>";
        }
    }

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        Label Label1 = (Label)Master.FindControl("Label1");
        Label1.Text = "<b>You chose <u>" + DropDownList1.SelectedValue + "</u> from the dropdown menu.</b>";
    }
}

and UI:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="labs_test" Title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
Type in text and then click button to display text in a Label that is in the MasterPage.<br />
This is done using FindControl.<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Submit" /><br />
<br />
Choose an item from the below list and it will be displayed in the Label that is
in the MasterPage.<br />
This is done using FindControl.<br />
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem>Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
<asp:ListItem>Item 3</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>    
</asp:Content>

Solution

  • Courtesy of Mr. Atwood himself, here's a recursive version of the method. I would also recommend testing for null on the control and I included how you can change the code to do that as well.

    protected void Button1_Click(object sender, EventArgs e)
    {
        if (TextBox1.Text != "")
        {
            Label Label1 = FindControlRecursive(Page, "Label1") as Label;
            if(Label1 != null)
                Label1.Text = "<b>The text you entered was: " + TextBox1.Text + ".</b>";
        }
    }
    
    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        Label Label1 = FindControlRecursive(Page, "Label1") as Label;
        if (Label1 != null)
            Label1.Text = "<b>You chose <u>" + DropDownList1.SelectedValue + "</u> from the dropdown menu.</b>";
    }
    
    private Control FindControlRecursive(Control root, string id)
    {
        if (root.ID == id) return root;
        foreach (Control c in root.Controls)
        {
            Control t = FindControlRecursive(c, id);
            if (t != null) return t;
        }
        return null;
    }