I am making a Wizard Control that contains combo boxes for user input. I am using TemplatedWizardStep
for the control over appearance and navigation. I have learned that accessing a control inside such a step requires use of FindControl(id)
.
My wizard looks basically like this, stripping out lots of formatting:
<asp:Wizard id="wizEntry" runat="server" >
<WizardSteps>
<asp:TemplatedWizardStep id="stepFoo" Title="Foo" runat="server" >
<table id="TableFoo" runat="server" >
<tr id="Row1">
<td id="Row1Cell1">
<asp:DropDownList id="DDListBar" runat="server" ></asp:DropDownList>
</td></tr></table></asp:TemplatedWizardStep></WizardSteps></asp:Wizard>
I want to get the selected value of DDListBar
inside wizard wiz
. My research shows that I should call FindControl
on the wizard to get the step, then on the step to get the control. My code:
DropDownList ddlBar = null;
bar = (DropDownList)wizEntry.FindControl("stepFoo").FindControl("DDListBar");
When I ran this, bar
came back as null
. So I split up the calls to FindControl
. I determined that the wizard step was being found properly, but not the combo box. In fact, the only control in the wizard step was the table.
I hope there's a simple solution that I have not learned, as opposed to FindControl for each level in the nested control hierarchy.
(The legacy code uses a long table with one combo box per row. The C# code file references those combo boxes directly by ID. But the table is Too Long, and the customer wants a wizard to break up the data entry into small units.)
Edit 1: This answer was helpful in my research so far.
Since DDListBar is nested inside TableFoo server control, you need to find it recursively.
Here is a helper method. It searches any control recursively.
public static Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
return root;
return root.Controls.Cast<Control>()
.Select(c => FindControlRecursive(c, id))
.FirstOrDefault(c => c != null);
}
var ddListBar = (DropDownList)FindControlRecursive(wizEntry, "DDListBar");