Search code examples
c#asp.netwebformswizardaspwizard

Finding a control in TemplatedWizardStep


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.


Solution

  • Since DDListBar is nested inside TableFoo server control, you need to find it recursively.

    Here is a helper method. It searches any control recursively.

    Helper Method

    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);
    }
    

    Usage

    var ddListBar =  (DropDownList)FindControlRecursive(wizEntry, "DDListBar");