Practical ASP.NET

Integrating Master Pages and Content Pages

Not content with providing a solution for displaying information from the Content page on its MasterPage, Peter returns to the topic to solve the problem from another direction.

In an earlier column ("Integrating Master Pages + Content Pages + a Little AJAX") I showed one way to display in a MasterPage information from the Content page it was displaying. The problem is relatively common: There is some information that you want to display in the same place on every page (and, as a result, you want to put it on the MasterPage) but the information you want to display is being provided by the Content page.

In that column, I added a property to the MasterPage and accessed it from the Content page using the Page object's Master property. This makes sense if you regard Content page as controlling the operation since it's providing the information and think of the MasterPage as the child of the Content page (not an unreasonable point of view, provided you don't take the "Master" in MasterPage too seriously).

MasterPage in Control
However, you could make a case that the MasterPage should be responsible for its own content and, as a result, the MasterPage should be controlling the process. From that point of view, if you wanted to update a Label on the MasterPage with the title of its Content page, you would use code in the MasterPage. This code, put in the MasterPage's Init, Load or PreRender events, would do the trick:

Me.PageTitleLabel.Text = Page.Title

This solution also means that you have to add code in only one place -- the MasterPage -- instead of having to update every Content page.

Unfortunately, this tactic works only as long as the information you want from the Content page is available from a property on the Page object. However, if the Content page is generating the information to be displayed in the MasterPage, then you'll need to add some code to the Content page. For instance, if you wanted to display the user's name and the page's Title, you could add a property like this to the Content page:

Public ReadOnly Property NameAndTitle() As String
  Get
    Return User.Identity.Name & ": " & Page.Title
  End Get
End Property

Accessing this custom property from the MasterPage is more complicated than accessing on the Page's property because, of course, my NameAndTitle property won't appear on the Page object. To access my custom property, I have to cast the Page object to the type of the Content page. It's not reasonable to cast to every different Content page type but there are at least two ways to avoid doing that:

  • Create a base class that inherits from Page and have all of the Content pages on the site inherit from that class instead of from the default Page class.

  • Create an interface that defines the property and have the Content page implement it.

If the property appears on all pages and the code in the property is usually the same in every page, the first option is probably the best way to go (if the code in the property does vary from one page to another, you can make the property override-able and replace it with page-specific code, as necessary). If, on the other hand, only some of your pages will need this property or the implementation is different on every page, the second option is probably your best choice.

Adding an Interface
If you do decide to use the Interface in a Web site (as opposed to a Web Project), you'll need to add a class file to the App_Code folder and then replace the default code with an Interface declaration. For some reason, the Add New Item dialog for Web sites doesn't include Interface files. Regardless of how you get there, an Interface that includes my property would look like this:

Public Interface IPHV

    Property ReadOnly NameAndTitle() As String

End Interface

To implement the interface in a Content page, I would use code like this to implement the interface and add code to it:

Partial Class CustomerOrders
    Inherits System.Web.UI.Page
    Implements IPHV

Public ReadOnly Property NameAndTitle() As String _ 
                  Implements IPHV
  Get
    Return User.Identity.Name & ": " & Page.Title
  End Get
End Property

Now, in the MasterPage's Load event, I can check to see if a page has implemented my interface and (if it has) access the property, as this code does:

If TypeOf Page Is IPHV Then
            Me.PageTitleLabel.Text = CType(Page, IPHV).TitleAndName
End If

So now you have two ways to integrate your MasterPage and Content page: Add properties to your MasterPage that you access from your Content page or add properties to your Content page and access them from your MasterPage. Your choice.

And thanks to Doug Rehnstrom who's been bugging me about this for years.

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

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

  • What's New for Python, Java in Visual Studio Code

    Microsoft announced March 2024 updates to its Python and Java extensions for Visual Studio Code, the open source-based, cross-platform code editor that has repeatedly been named the No. 1 tool in major development surveys.

Subscribe on YouTube