Find ContentPlaceHolders in Master page
I'm looking for a way to dynamically load a master page in order to get a collection of ContentPlaceHolders within.
I would prefer not to have to load a page object to assign the master page to before I can access it's controls, but if that's the only way I'll be happy to use it. This is the way I was hoping it would work:
开发者_StackOverflow中文版Page page = new Page();
page.MasterPageFile = "~/home.master";
foreach (Control control in page.Master.Controls)
{
if (control.GetType() == typeof(ContentPlaceHolder))
{
// add placeholder id to collection
}
}
But page.Master
throws a null reference exception. It only seems to load at some point when an actual page has been created in the page lifecycle.
I even thought of dynamically changing the current page's MasterPageFile on Page_Init(), reading all ContentPlaceHolders then assigning the original MasterPageFile back, but that would be horrible!
Is there a way to load a master page into memory independent of an actual page so that I can access properties of it?
My final resort will probably involve parsing the master page contents for ContentPlaceHolders instead, which isn't as elegant but might be a bit faster.
Anyone able to help please? Many thanks.
You should be able to use LoadControl to load the master page an enumerate the Controls collection.
var site1Master = LoadControl("Site1.Master");
To find the Content Controls you will need to recursively search the Controls collection. Here is a quick and dirty example.
static class WebHelper
{
public static IList<T> FindControlsByType<T>(Control root)
where T : Control
{
List<T> controls = new List<T>();
FindControlsByType<T>(root, controls);
return controls;
}
private static void FindControlsByType<T>(Control root, IList<T> controls)
where T : Control
{
foreach (Control control in root.Controls)
{
if (control is T)
{
controls.Add(control as T);
}
if (control.Controls.Count > 0)
{
FindControlsByType<T>(control, controls);
}
}
}
}
The above can be used as follows
// Load the Master Page
var site1Master = LoadControl("Site1.Master");
// Find the list of ContentPlaceHolder controls
var controls = WebHelper.FindControlsByType<ContentPlaceHolder>(site1Master);
// Do something with each control that was found
foreach (var control in controls)
{
Response.Write(control.ClientID);
Response.Write("<br />");
}
精彩评论