Finding ASP.NET Child Controls....the Simple Way
My good buddy Spike Xavier and I were discussing how to find nested child controls today and we discovered a nice trick that can be used. In the past, I've used parentControlID$childControlID syntax with the SqlDataSource and parameters to identify TextBox controls nested within a DetailsView control without resorting to C# or VB.NET code. This type of syntax allows the page to query the parent control and then locate the target child control (the $ acts as the delimiter). Spike needed to use the DefaultFocus attribute of the <form> element to set the focus to a TextBox nested within a FormView control. We tried listing the TextBox ID directly in DefaultFocus and it didn't work (which was expected since it's a nested control). We then used the syntax I had used previously with the SqlDataSource control in DefaultFocus and it worked....the TextBox received focus when the page loaded.
Here's a simple example that contains a FormView control named formVw with a TextBox inside of it named txtName:
<form id="form1" runat="server" DefaultFocus="formVw$txtName">
<div>
<asp:FormView ID="formVw" runat="server">
<ItemTemplate>
Name:
<asp:TextBox ID="txtName" runat="server"
Text='<%# Eval("FirstName") + " " + Eval("LastName") %>' />
</ItemTemplate>
</asp:FormView>
</div>
</form>
Notice that the DefaultFocus attribute refers to the parent control first (the FormView) and then to the child control (the TextBox) using the formVw$txtName syntax. There are several other ways to do this but none are as simple. I experimented a little more and found out that this technique also works with FindControl(). The Page class's FindControl() method only searches for direct children. It won't search grandchildren or lower descendents. However, using the parentID$childID syntax FindControl() will walk the page's control hierarchy. For example, to get to txtName (shown above) starting from the root of the page the following syntax can be used:
TextBox tb = this.FindControl("form1$formVw$txtName") as TextBox;
if (tb != null)
{
//Access TextBox control
}
This is of course a loosely bound operation (quotes are being used so the compiler won't catch typos in the quotes) so I wouldn't recommend it if a strongly-bound technique is available for a given situation. However, it's quite useful in some situations. I haven't come across any issues with this technique (although I'm guessing there are some) but will post them if I come across any. The simple ASP.NET Website I created to demonstrate these concepts can be downloaded from the following URL:
http://www.xmlforasp.net/CodeBank/Download/Blog/FindingControls.zip