Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET - FindControl in nested master page

How to conveniently access a control within a nested master page?


Accessing master page controls is usually straight forward:

Dim ddl As DropDownList = Master.FindControl("ddl")

However when my setup is as follows the control cannot be found, presumably becuase the control is within a content block:

1 Root Master

<asp:ContentPlaceHolder ID="cphMainContent" runat="server" />

2 Nested Master

<%@ Master Language="VB" MasterPageFile="~/Root.master" AutoEventWireup="false" CodeFile="Nested.master.vb" Inherits="Nested" %>

<asp:Content ID="MainContent" ContentPlaceHolderID="cphMainContent" runat="server">
  <asp:DropDownList ID="ddl" runat="server" DataTextField="Text" DataValueField="ID"/>
</asp:Content>

3 Content Page VB.NET

Dim ddl As DropDownList = Master.FindControl("ddl")

Workaround

I have found a solution by traversing up the tree finding the root content placeholder cphMainContent and then looking for the control within.

cphMainContent = CType(Master.Master.FindControl("cphMainContent"), ContentPlaceHolder)
Dim ddl As DropDownList = cphMainContent .FindControl("ddl")

However this solution seems very roundabout and inefficient.

Can the control be accessed directly from within the content block of the master page?

like image 334
DreamTeK Avatar asked Sep 20 '25 07:09

DreamTeK


1 Answers

Here is an extension method that can handle an arbitrary number of nesting levels:

public static class PageExtensions
{
    /// <summary>
    /// Recursively searches this MasterPage and its parents until it either finds a control with the given ID or
    /// runs out of parent masters to search.
    /// </summary>
    /// <param name="master">The first master to search.</param>
    /// <param name="id">The ID of the control to find.</param>
    /// <returns>The first control discovered with the given ID in a MasterPage or null if it's not found.</returns>
    public static Control FindInMasters(this MasterPage master, string id)
    {
        if (master == null)
        {
            // We've reached the end of the nested MasterPages.
            return null;
        }
        else
        {
            Control control = master.FindControl(id);

            if (control != null)
            {
                // Found it!
                return control;
            }
            else
            {
                // Search further.
                return master.Master.FindInMasters(id);
            }
        }
    }
}

Use the extension method from any class inheriting from System.Web.UI.Page like so:

DropDownList ddl = (DropDownList)Page.Master.FindInMasters("ddl");
if (ddl != null)
{
    // do things
}
like image 174
crenshaw-dev Avatar answered Sep 21 '25 22:09

crenshaw-dev