I've been busily converting one of my apps to ASP.NET 2.0 as well as updating some core components and the base databinding mechanism of my overall framework. This app didn't really need an update from a functional perspective, but I used the application as my proving ground for a number of new concepts and ideas I've been tossing around – most of which have been discussed here at one time or another.
One thing that's still throwing me for a loop once a while is MasterPages. I'm still finding a few things here and there that are not quite natural to deal with. Here's one of them.
In my app I have several master pages for different 'areas' of the application. The main public facing interface gets one masterpage, the admin areas another and the reporting end another. Master Pages work great for basic skinning support and the ability to customize the layout.
But one thing that I've repeatedly run into is styling of pages dynamically. The Masters define the head section so all style references come for the theme CSS file(s). But on a number of pages – especially the admin pages – I need to customize the existing styles and or create one off styles for a specific page.
Easier said than done with MasterPages, since the style is defined in the head tag of the MasterPage. You can't easily define a Style tag inside of a Content panel:
<style>
.gridheader { text-align:center;height:20px;padding-top:2px; }
</style>
If you do something like this right in your Content Panel, the HTML will actually work, but it's actually badly formatted HTML. Worse – Visual Studio in won't let you switch into design view with a style tag inside of your content (depending on how your page is laid out but if it's between a <td> or <div> tag it won't let you).
So how do you get a style tag into the header? You could do it programmatically but the syntax for adding individual styles is not exactly short or intuitive. In fact, on a quick search I couldn't figure out how to do it short of writing out raw text into the header with a literal control (I'm sure there's an easier way though). Anyway, I don't think this is a workable solution.
The solution I settled on is this: Using a second content panel in the MasterPage that essentially extends the header into the Content pages.
<head runat="server">
<title></title>
<link runat="server" id="styleTemp"
href="../../App_Themes/Standard/Standard.css"
rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder runat="server" id="Headers">
</asp:ContentPlaceHolder>
</head>
<body style="margin-top: 0px; margin-left: 0px">
If you don't need to add any headers to your content page – fine. Nothing further is needed. But if you now need to add say a stylesheet you can do this in the content page:
<%@ Page Language="c#" Inherits="Westwind.WebStore.Admin.EditInventoryItem" >
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Headers">
<style>
.gridheader { text-align:center;height:20px;padding-top:2px; }
</style>
</asp:Content>
<asp:Content ContentPlaceHolderID="Content" ID="Content" runat="server">
<h1>Inventory Item Edit Form</h1>
…
</asp:Content>
This solves the problem of giving the content page access to the header which is the one place where the client might need access to the content of the master. You can add styles, meta tags, scripts or whatever you want in the header right here.
Eeer, just as I'm finishing this up I notice that K.Scott Allen posted a similar note about a month ago. I suppose this is good enough of a tip to pass on again <g>.
One thing he mentions that I missed it that the Visual Studio HTML validation complains about the content placeholder in the header. But then again VS.NET complains about a lot of things that are legit <shrug>…
Other Posts you might also like