Building an AJAX enabled ASP.NET application we encountered the effect mentioned in the title of this article.
There is a TabContainer with a TabPanel containing a TextBox.
<cc1:TabPanel runat="server" ID="TabPanel1" TabIndex="0" HeaderText="Person">
<ContentTemplate>
<asp:TextBox ID="TextBoxName" runat="server"></asp:TextBox>
</ContentTemplate>
</cc1:TabPanel>
This TextBox is accessible via a member variable, which is automatically created by Visual Studio Designer:
this.TextBoxName.Text = "Enter name here...";
If you try to access the TextBox using FindControl() method of Page class, you will be alerted with following message:
The error message is: “Object reference not set to an instance of an object.”.
That means, the FindControl() method cannot find the control by specified ID an returns null.
Slightly surprised (the TextBox is still accessible via member variable) we looked towards Microsoft Knowledge Base and Forums and found following article: http://msdn.microsoft.com/en-us/library/y81z8326%28v=vs.90%29.aspx#Y2166
It says: “When a control is not inside a naming container, you can get a reference to it by using the control's ID. When a control is inside a naming container, you must call a method that searches the naming container for the control's ID. A control might also be inside a naming container that you do not have direct access to.”
To access a control by its ID inside a naming container, you have to extend your Page by instance method FindControlRecursive() described in the referenced article as well:
…
((TextBox)this.FindControlRecursive(this,"TextBoxName")).Text = "Enter name here...";
…
private Control FindControlRecursive(Control rootControl, string controlID)
{
if (rootControl.ID == controlID) return rootControl;
foreach (Control controlToSearch in rootControl.Controls)
{
Control controlToReturn =
FindControlRecursive(controlToSearch, controlID);
if (controlToReturn != null) return controlToReturn;
}
return null;
}
It works! Enjoy…