this is an old question but i have a robust solution for anyone who stumbles upon this.
in app_code, create a file and paste this code:
namespace MasterControls
{
// code written by alexander taylor on 2011-08-22. http://www.alexsapps.com
public abstract class ChildUserControl : UserControl
{
Control master;
public abstract string MasterControlVirtualPath { get; }
protected override void OnInit(EventArgs e)
{
master = LoadControl(MasterControlVirtualPath);
Controls.Add(master);
base.OnInit(e);
}
protected override void Render(HtmlTextWriter writer)
{
master.RenderControl(writer);
}
}
public class ControlContentPlaceHolder : Control
{
protected override void Render(HtmlTextWriter writer)
{
ControlContent found = null;
foreach (Control c in NamingContainer.NamingContainer.Controls)
{
ControlContent search;
search = c as ControlContent;
if (search != null && search.ControlContentPlaceHolderID.Equals(ID))
{
found = search;
break;
}
}
if (found != null)
{
//write content of the ContentControl
found.RenderControl(writer);
}
else
{
//use default content
base.Render(writer);
}
}
}
public class ControlContent : Control
{
public string ControlContentPlaceHolderID { get; set; }
}
}
example "master control" (equivalent of master page)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MasterControl1.ascx.cs" Inherits="MasterControl1" %>
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %>
<p>content 1 below:<br />
<masterControls:ControlContentPlaceHolder ID="myContent1" runat="server">
default content 1 here!
</masterControls:ControlContentPlaceHolder></p>
<p>content 2 below:<br />
<masterControls:ControlContentPlaceHolder ID="myContent2" runat="server">
default content 2 here!
</masterControls:ControlContentPlaceHolder></p>
example "child control" (equivalent of page)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ChildControl1.ascx.cs" Inherits="Control1" %>
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %>
<masterControls:ControlContent ControlContentPlaceHolderID="myContent1" runat="server">
custom content 1
</masterControls:ControlContent>
<masterControls:ControlContent ControlContentPlaceHolderID="myContent2" runat="server">
custom content 2
</masterControls:ControlContent>
in the code behind of the child control
using MasterControls;
//you must inherit the ChildUserControl class!
public partial class Control1 : ChildUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public override string MasterControlVirtualPath
{
//below, type the location to the master control
//you wish to apply to this control
get { return "~/MasterControl1.ascx"; }
}
}