When there is nested master pages and when we try to access the control inside the base master page, you will get an error "NullReferenceException". The reason is ASP.NET didn't have the method to find the control in recursive.
To explain in detail, we have BaseMaster.master file
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="BaseMaster.master.cs" Inherits="MasterPage" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>XTP Site Manager</title> <asp:ContentPlaceHolder id="head" runat="server"></asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <div id="div_body"> <asp:ContentPlaceHolder id="body" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html>
Another Master file which inherits BaseMaster, HomeMaster.master
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="HomeMaster.master.cs" Inherits="MasterPages_HomeMaster" MasterPageFile="~/MasterPages/BaseMaster.master" %> <asp:Content runat="server" ID="Content1" ContentPlaceHolderID="body"> <!-- HEADER --> <div id="div_header" runat="server" style="position: absolute; top: 0px; left: 0px; width: 900px; height: 100px"> <asp:contentplaceholder id="Header" runat="server"> </asp:contentplaceholder> </div> <!-- LEFT NAV --> <div id="div_leftnav" runat="server" style="position: absolute; top: 100px; left: 0px; width: 200px; height: 500px"> <asp:contentplaceholder id="LeftNav" runat="server"> </asp:contentplaceholder> </div> <!-- CENTER CONTENT --> <div id="div_content" runat="server" style="position: absolute; top: 100px; left: 200px; width: 550px; height: 500px"> <asp:contentplaceholder id="Center" runat="server"> </asp:contentplaceholder> </div> <!-- RIGHT NAV --> <div id="div_rightnav" runat="server" style="position: absolute; top: 100px; left: 750px; width: 150px; height: 500px;"> <asp:contentplaceholder id="RightNav" runat="server"> </asp:contentplaceholder> </div> <!-- FOOTER --> <div id="div_footer" runat="server" style="position: absolute; top: 600px; left: 0px; width: 900px; height: 100px;"> <asp:contentplaceholder id="Footer" runat="server"> </asp:contentplaceholder> </div> </asp:Content>
Now we have default page which inherits HomeMaster.master and in the codebehind we will try to add an user control to the master page.
ContentPlaceHolder cp = new ContentPlaceHolder(); cp = Page.FindControl("Header") as ContentPlaceHolder; if (cp != null) { UserControl uc = this.LoadControl("usercontrols/static_widget.ascx") as UserControl; cp.Controls.Add(uc); }
public static class PageExtensionMethods { public static Control FindControlRecursive(this Control ctrl, string controlID) { if (string.Compare(ctrl.ID, controlID, true) == 0) { // We found the control! return ctrl; } else { // Recurse through ctrl's Controls collections foreach (Control child in ctrl.Controls) { Control lookFor = FindControlRecursive(child, controlID); if (lookFor != null) return lookFor; // We found the control } // If we reach here, control was not found return null; } } }
ContentPlaceHolder cp = new ContentPlaceHolder(); cp = Page.FindControlRecursive("Header") as ContentPlaceHolder; if (cp != null) { UserControl uc = this.LoadControl("usercontrols/static_widget.ascx") as UserControl; cp.Controls.Add(uc); }