Search code examples
c#asp.netfindcontrol

Find Control Deep Inside LoginView


I have a login view control that I can find with findcontrol. Inside it is LoggedInTemplate->ul->li->ul->li->a. How can I find a? Here is sample code:

   <asp:LoginView runat="server" ViewStateMode="Disabled" ID="a">
          <LoggedInTemplate>
                 <ul class="nav navbar-centered navbar-nav" id="second-menu" role="menu" >
                     <li class="dropdown"><a runat="server" href="" class="dropdown-toggle" >AB</span></a>
                        <ul class="dropdown-menu">
                            <li><a runat="server" id="link">Link</a></li>

This works:

LoginView a = (LoginView)this.Master.FindControl("a");

But this doesn't:

HyperLink dashboardLink = (HyperLink)a.FindControl("link");

Solution

  • From the MSDN page of FindControl:

    This method will find a control only if the control is directly contained by the specified container; that is, the method does not search throughout a hierarchy of controls within controls. For information about how to find a control when you do not know its immediate container, see How to: Access Server Controls by ID.

    So you have to write your own recursive find method:

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

    Which you can use like this:

    LoginView a = (LoginView)this.Master.FindControl("a");
    HyperLink dashboardLink = (HyperLink)FindControlRecursive(a,"link");
    

    or simply:

    HyperLink dashboardLink = (HyperLink)FindControlRecursive(this.Master,"link");
    

    But for that to work, you will have to use

    <a runat="server" ID="link">Link</a>
    

    as "ID" is case-sensitive, as far as I know.

    Edit: According to this MSDN page, you can access that control by simply using it's name (ID).

    When a control is not inside a naming container, you can get a reference to it by using the control's ID.

    The article has sample code too.