Reputation: 34307
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?
Upvotes: 4
Views: 2102
Reputation: 8412
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
}
Upvotes: 3