Click here to Skip to main content
Licence CPOL
First Posted 12 Feb 2007
Views 75,469
Downloads 910
Bookmarked 65 times

Really Dynamic Master Pages

By szukuro | 3 Nov 2009
Creating ContentPlaceHolders and Contents programmatically

1
2 votes, 16.7%
2
3 votes, 25.0%
3
1 vote, 8.3%
4
6 votes, 50.0%
5
3.54/5 - 12 votes
μ 3.54, σa 2.17 [?]

Introduction

Master pages are a very cool feature in ASP.NET 2.0. They allow you to easily create a consistent look and feel throughout your website. They also provide an easy way to set/change the master pages at runtime. This is achieved by setting the MasterPageFile property of a page in the PreInit event. This, however, requires that the master pages have ContentPlaceHolders which the Content controls on the page reference through the ContentPlaceHolderID property. This article focuses on creating ContentPlaceHolders, Contents and linking them together programmatically.

Background

When I first used ASP.NET 2.0, one of the first features I used were master pages. I soon learned how to switch between such at runtime. Some time later, I was working on a small project, where the goal was to create as many things dynamically as possible (kind of a web application framework). I had a thought about using master pages that are stored in a DB (as metadata) and then later building them dynamically. I soon found out that this task is not as easy as it looks. It requires more than just the knowledge of how to create controls through code. I did some research on how to properly do this and I wanted to share this technique, hence this article was born.

Using the Code

The sample provided contains two pages and a master page. Its only purpose is to demonstrate how things are done. On the start page (Default.aspx), you are to enter a number, press a button and let the magic begin. Despite the visually not very attractive result on the next page (only some text can be seen), the magic still does happen in the background. Let's see what happens. For this, you should have some knowledge about the ASP.NET page lifecycle.

The most important step is to create the content on the page. You will be surprised to find that no creation of Content classes is necessary. Instead you should use the AddContentTemplate method of the Page class. Chances are you never heard of this method, it is because it has the [EditorBrowsable(EditorBrowsableState.Never)] attribute applied and thus isn't visible for IntelliSense. MSDN has some information about it, you can read it here. You need two parameters, the first being the name of the ContentPlaceHolder it will be linked to (you can only set the ContentPlaceHolderID attribute in the markup), the other an ITemplate. If you have never worked with templated controls, you should find this a bit complicated, but it really isn't. However explaining this still goes beyond the reach of this article. In this example, all the content is the same, but that's not obligatory, then again easier to implement and satisfactory for demonstration purposes.

protected void Page_PreInit(object sender, EventArgs e)
{
    //...same check as in the constructor of the Master Page 
    for (int i = 1; i < num + 1; i++)
        base.AddContentTemplate("ContentPlaceHolder" + i.ToString(),
            new CompiledTemplateBuilder(new BuildTemplateMethod(this.Build)));
}

Using constructors in ASP.NET is a very uncommon scenario, but in this case there's no other place to put the code needed, because the master page's Init event is already too late and there's no PreInit event. You just need to add the names of the ContentPlaceHolder controls to be created later to the ContentPlaceHolders collection of the Master class. Note that you must use the names in lowercase.

public MasterPage()
{
   object cphnum = HttpContext.Current.Session["cphnum"];
   if (cphnum == null || !(cphnum is int))
      return;
   num = (int)cphnum;
   for (int i = 1; i < num + 1; i++)
      base.ContentPlaceHolders.Add("contentplaceholder" + i.ToString()); 
}

Finally you should instantiate the ContentPlaceHolders and add them to the control hierarchy of the page. This is also achieved in a for loop, so that the required number of controls gets created. For this purpose, you must use the ContentTemplates collection the master pages base, which as of type is an ITemplate.

protected void Page_Init(object sender, EventArgs e)
{
    //...
    for (int i = 1; i < num + 1; i++)
    {
    ContentPlaceHolder cph = new ContentPlaceHolder();
    cph.ID = "ContentPlaceHolder" + i.ToString();
    PlaceHolder1.Controls.Add(cph);
    ((ITemplate)base.ContentTemplates["ContentPlaceHolder" +
        i.ToString()]).InstantiateIn(cph);
    }
}

Now that you know the basics, you can easily extend the sample to be more useful than its current form.

History

  • 12.02.2007 - Initial posting of the article
  • 16.04.2007 - Added VB.NET demo

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

szukuro

Web Developer

Hungary Hungary

Member
I'm a Hungarian developer interested mostly in web development.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionAdding aspx page dynamically and applying Master page PinmemberParashuramr12120:28 18 Jan '12  
Generalnested master Pinmembermduhovich11:21 20 Jul '10  
GeneralInstantiateIn causes CreateChildControls to happen at inopportune times Pinmembernbarger19:49 19 Nov '08  
QuestionHow to fill a contentPlaceholder in a template ? Pinmemberlesta6:06 8 Nov '07  
AnswerRe: How to fill a contentPlaceholder in a template ? Pinmemberszukuro22:37 11 Nov '07  
QuestionOnly 1 Placeholder allowed? PinmemberElroy Skimms4:38 19 Sep '07  
AnswerRe: Only 1 Placeholder allowed? Pinmemberszukuro13:12 24 Sep '07  
GeneralRe: Only 1 Placeholder allowed? PinmemberElroy Skimms15:41 24 Sep '07  
Generalerror in content page Pinmemberveerbala3:55 18 Apr '07  
GeneralRe: error in content page Pinmemberszukuro6:15 18 Apr '07  
GeneralRe: error in content page Pinmemberveerbala6:46 18 Apr '07  
GeneralRe: error in content page Pinmemberveerbala7:36 18 Apr '07  
QuestionHow to write html code in a ContentPlaceHolder in Master page Pinmembergorkemdur5:05 17 Apr '07  
AnswerRe: How to write html code in a ContentPlaceHolder in Master page Pinmemberszukuro22:15 17 Apr '07  
GeneralRe: How to write html code in a ContentPlaceHolder in Master page Pinmembergorkemdur4:18 18 Apr '07  
QuestionIs there a VB version? Pinmemberreg200616:04 15 Apr '07  
AnswerRe: Is there a VB version? Pinmemberszukuro1:04 16 Apr '07  
GeneralRe: Is there a VB version? Pinmemberreg200617:25 16 Apr '07  
GeneralDynamically filling placeholders PinmemberDaveWarren1:44 12 Apr '07  
GeneralRe: Dynamically filling placeholders Pinmemberszukuro9:09 12 Apr '07  
GeneralRe: Dynamically filling placeholders PinmemberDaveWarren10:11 12 Apr '07  
GeneralRe: Dynamically filling placeholders Pinmemberszukuro13:01 12 Apr '07  
GeneralRe: Dynamically filling placeholders PinmemberDaveWarren2:50 13 Apr '07  
GeneralDynamic Masterpage Content PinmemberPaul Molloy7:02 2 Apr '07  
GeneralRe: Dynamic Masterpage Content Pinmemberszukuro12:42 2 Apr '07  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120210.1 | Last Updated 3 Nov 2009
Article Copyright 2007 by szukuro
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid