FindControl Returning Null

nickson104 picture nickson104 · Apr 7, 2015 · Viewed 10k times · Source

I am trying to contol a buttons state depending on a relevant text box. The names are the same other than the prefixes. The text boxes and buttons are located in a table on the page.

<asp:Table ID="Table1" runat="server" CssClass="table">
            <asp:TableRow>
                <asp:TableCell Width="15%">
                    <asp:Label ID="lblRequestHeader" runat="server" Text="Requested" CssClass="bold text-center"
                        Width="90%"></asp:Label>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Label ID="lblApprovalHeader" runat="server" Text="Approval" CssClass="bold text-center"
                        Width="90%"></asp:Label>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Label ID="lblApprovalTimeHeader" runat="server" Text="Date/Time of Approval"
                        CssClass="bold text-center" Width="90%"></asp:Label>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Label ID="lblReadyHeader" runat="server" Text="Ready To Pick Up" CssClass="bold text-center"
                        Width="90%"></asp:Label>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Label ID="lblCollectedHeader" runat="server" Text="Collected By TestHouse" CssClass="bold text-center"
                        Width="90%"></asp:Label>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Label ID="lblDeliveredHeader" runat="server" Text="Delivered From TestHouse"
                        CssClass="bold text-center" Width="90%"></asp:Label>
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
                <asp:TableCell Width="15%">
                    <asp:TextBox ID="txtRequestTime" runat="server" Width="90%"> </asp:TextBox>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:TextBox ID="txtApproval" runat="server" Width="90%"></asp:TextBox>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:TextBox ID="txtApprovalTime" runat="server" Width="90%"></asp:TextBox>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:TextBox ID="txtReadyTime" runat="server" Width="90%"></asp:TextBox>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:TextBox ID="txtCollectedTime" runat="server" Width="90%"></asp:TextBox>
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:TextBox ID="txtDeliveredTime" runat="server" Width="90%"></asp:TextBox>
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
                <asp:TableCell Width="15%">
                </asp:TableCell>
                <asp:TableCell Width="15%">
                </asp:TableCell>
                <asp:TableCell Width="15%">
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Button ID="btnReadyTime" runat="server" Text="Ready To Collect" Width="90%" />
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Button ID="btnCollectedTime" runat="server" Text="Collected" Width="90%" />
                </asp:TableCell>
                <asp:TableCell Width="15%">
                    <asp:Button ID="btnDeliveredTime" runat="server" Text="Delivered" Width="90%" />
                </asp:TableCell>
            </asp:TableRow>
        </asp:Table>

The textbox is populated by a dataretrieval, and the state of the button is then set by the called method as follows:

txtReadyTime.Text = slabdetails.ReadyTimestamp.ToString();
textboxenabled(txtReadyTime);

This method modifies the textbox name to a button name, then attempts to find the button to enable/disable it.

 public void textboxenabled(TextBox box)
    {
       string btnName = box.ID.Replace("txt", "btn");
        try
        {
            Button btn = FindControl(btnName) as Button;
            if (box.Text == "")
                btn.Enabled = true;
            else
                btn.Enabled = false;
        }
        catch
        {
        }
    }

However, despite the string matching the names of the buttons perfectly, the control returns as null. What can be done to deal with this issue?

Answer

nickson104 picture nickson104 · Apr 7, 2015

With thanks to Matthew Watson, the FindControl has issues in projects using master pages. In order to find controls within a page, one must first drill down through the master page and its content manually:

This:

  Button btn = FindControl(btnName) as Button;

Must take the format:

  Button btn = this.Master.FindControl("MainContent").FindControl(btnName) as Button;