How to programmatically assign a SkinID to a control while using a master page in ASP.net 2.0
Using themes in ASP.net allows you to "skin" the look and feel of a web site, much like CSS, but with more control, because now you can affect the rendering of the HTML in server controls.
The recommended use of a theme is to put as much as possible in the CSS, which can be used in conjuction with the theme folder. In fact, the theme has a nice built in feature of automatically writing the <link> markup to your ASPX page automatically for the CSS file you place within the theme.
A theme can contain many ways to render the same server side control. Each possible way of rendering the control is identified by a SkinID property in the theme, which you then assign to your instance of the control in your page or masterpage.
There are two main ways of assigning both a page theme and its skinID's to the controls within your page: either declaritively in your markup, or programmatically in your code. Assigning skinID's in your markup is great, unless you want a bit more control over the SkinID to assign. For example, you may want to assign a SkinID dynamically based on settings in the users Profile object.
So, how do you do this? Well, the answer is you must assign the theme and skinID of controls early on in the page lifecycle, in the PreInit event. This event fires before initialzation of the controls begins, meaning that the theme is able to effect the render before the render is started. All this makes sense, and all is well in the world. The following code sample demostrates this:
void Page_PreInit(object sender, EventArgs e)
{
Calendar1.SkinID = "MySkin";
}
Now, what happens if you try this applying a masterpage at the same time? You get an "object reference not set to an instance of an object" exception, and when examine the event, it is clear why this happening - all the controls in the PreRender event are set to null - ie not instantiated yet.
What is going on here? This is currently an undocumented feature of using Masterpages with skins. When you use apply a masterpage to your page, the controls in your page are not available until the control tree of the masterpage has been instantiated. Thus, when you access PreInit on the page, nothing is instantiated yet, because the Masterpages controls are not available.
So what is the answer? Well, the PreInit event must now look like this:
void Page_PreInit(object sender, EventArgs e)
{
System.Web.UI.MasterPage m = Master;
Calendar1.SkinID = "MySkin";
}