One common request from developers when they learn about themes in ASP.NET 2.0 is for a way to set the theme globally at runtime. Unfortunately there is no simple way to do this, although there are ways, as
several people have posted in the past. The one technique that I have favored is to add a handler for the PreRequestHandlerExecute event in global.asax and register a new PreInit handler for each page, setting the theme in the new handler. This technique can be applied to a site without changing anything else in the site, including the base class of each page (which is another common approach).
Here's an example of overriding the handler in global.asax and setting the theme dynamically based on a Profile property called "theme":
// In global.asax
void Application_PreRequestHandlerExecute(object src, EventArgs e)
{
Page p = this.Context.Handler as Page;
if (p != null)
{
p.PreInit += new EventHandler(page_PreInit);
}
}
void page_PreInit(object sender, EventArgs e)
{
Page p = this.Context.Handler as Page;
if (p != null)
{
p.Theme = (string)Context.Profile["theme"];
}
}
I was demonstrating this technique at a conference talk recently, and someone asked if you could do the same thing with StyleSheetTheme (which is basically the same thing as Theme, except that it applies the skin properties of controls before the declarative attributes of a control on a page are applied). To my surprise, it failed with an exception stating that you must override the StyleSheetTheme property of the page class to change it (unlike the Theme property which you can just set). So apparently the only way to set the StyleSheetTheme globally is to override the virtual property:
public override String StyleSheetTheme
{
get { return Profile.theme; }
}
This is fine if you have access to the page to override the property, but it means that you can't use the same global injection technique that you can for the Theme attribute. The closest you can get is to create a common base class for all the pages in your site and override the StyleSheetTheme property. You then must go through all of your pages and have them inherit from this new base class instead of Page (this includes both code behind file classes and direct pages without code behind). Bleh. I'll stick with "Theme" and keep the relatively clean handler injection…
Posted
Aug 02 2006, 08:00 AM
by
fritz-onion