Practical .NET

ASP.NET: Empowering Your Master Pages

You can use your Master Pages just to structure your pages. Or you can integrate them into your application with custom code that your content pages can access.

In addition to using Master Pages to provide a common structure for your pages, you can also enable your Master Pages with code. At its simplest, you can have a control on your Master Page that reflects the content page that's currently being displayed -- a "Page Title" box, for instance, that displays a name set by the current content page. But if you want to add some code to your site to perform the same operation on every page on the site (vetting entries to controls on every page, for instance), one place you could put that code is in your Master Page.

From Master Page to Content Page
First, the bad news: From code in the Master Page, you can't access the content page currently being displayed; at least, not as a Page object. You can, however, access the controls that the content page has placed in the Master Page's ContentPlaceHolders.

The easiest way to access the controls added to your Master Page is through a set of properties added to your Master Page for every ContentPlaceHolder on the Master Page. These properties are given a name based on the ContentPlaceHolder's ContentControlId. If, for instance, you have a ContentPlaceHolder called Messages on the page, you can access the controls it contains with code like this:

For Each ctrl In Me.Messages.Controls
    '…process controls…
  Next

To process all the controls on the page, you might be tempted to use the Master Page's ContentPlaceHolders collection. However, it doesn't contain a collection of your ContentPlaceHolder objects; it contains a collection of the names of your ContentPlaceHolder objects which you can then use with the FindControl method to process all the actual ContentPlaceHolder.

Putting that together to create a method that processes all the controls that a content page added to your Master Page, you would write code like this:

  Public Sub ProcessAllControls
    Dim cph As ContentPlaceHolder
    For Each Name As String In Me.ContentPlaceHolders
      cph = Me.FindControl(Name)
      For Each ctrl As Control In cph.Controls
        '…process controls…
      Next
    Next
  End Sub

You don't have to put that code in a method, of course; you can put code in the Master Page's events as you would with a standard content page. The Master Page fires the same events as your content page, with one exception: The Master Page doesn't fire a PreInit event. The Master Page's events always fire after the content page's events (e.g. the content page's Init event fires, then the Master Page's Init event). There is, again, one exception: The Master Page's Unload event fires before the content page's Unload event.However, putting the code in a method lets you control, from your content page, when that code executes.

From Content Page to Master Page
While you can't really access a content page from a Master Page, you can access a Master Page from a content page. This becomes useful if you add properties and methods to your MasterPage that you can then access from your content pages. For instance, this custom property, added to a Master Page, updates a control on the Master Page:
  Public Property PageTitle() As String
    Get
      Return Me.PageTitleLabel.Text
    End Get
    Set(ByVal value As String)
      Me.PageTitleLabel.Text = value
    End Set
  End Property

  mp.PageTitle = "Customer Image"

To access that property, your content page must first access its Master Page through the content page's MasterPage property. However, this returns the generic class for your Master Page, and your content page is being displayed by the specific Master Page that contains your custom properties or methods. However, you can cast the object returned by the MasterPage property to your Master Page's type with code like this:

Dim mp As MyMaster
mp = CType(Me.Master, MyMaster)

After casting the MasterPage reference, you can add code in your content page to use any custom methods or properties in your Master Page. This code uses the custom PageTitle property to update the Master Page's PagetTitleLabel control:

mp.PageTitle = "My  Page"

Similarly, the my custom method to process all the controls on the page code could be run from the content page like this:

mp.ProcessAllControls

As you can see, your Master Pages don't have to be simple repositories for common controls. Instead, you can integrate your own code into your Master Page to make it part of your application's processes.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

Subscribe on YouTube