Themes and Skins


The other major user interface consolidation feature ASP.NET 2.0 introduces is the ability to create themes for your sites. A theme is a collection of user interface elements, like stylesheets, images, and skins, consolidated into a single directory, which can then be applied to an individual page across all pages in a site. Once you have defined a theme for use in your site, you can create a copy of that theme and make changes to the interface elements to create an alternate look and feel that can be applied to pages in your site as well, giving your site the ability to take on different "skins." These skins can be applied statically through Page attributes, or dynamically, often in response to user preferences. Figure 2-7 shows an example of two different skins being applied to a page that alter the appearance of controls on that page.

Figure 2-7. Theme concept


Themes

Technically, a theme is a subdirectory beneath a site's top level App_Themes directory. The name of each subdirectory becomes a theme available for applications within the site. Inside the directory, you can place .skin files, .css files, other files that may be referenced by .skin or .css files (like image files, JScript files, text files, etc.), and additional subdirectories containing resource files that may be referenced by .skin or .css files (like /images or /scripts). The advantage of including .css files in a theme directory is that every page with this theme applied will have a link added to its <head> element for each .css file in the theme. In addition, references to files contained in subdirectories are implicitly prefixed with the full virtual path to the subdirectory containing the resource, so they are valid from any page in the site. Both .css files as well as .skin files (which we will discuss next) must be placed at the top level of a theme directory to take effect.

Skin files are conceptually like cascading stylesheets for ASP.NET server-side controls. A .skin file consists of a collection of control declarations with properties (you can apply any properties you like, but you can't include an ID attribute). The properties defined by each control will be applied to all instances of that control on pages to which the enclosing theme is applied. For example, Listing 2-14 shows a skin file (Day.skin) that shows three different control declarations with several properties populated. When this skin file is applied to a page, all instances of Button, Calendar, and TextBox controls will take on the properties defined in the skin when the page is prepared for rendering, as shown in Figure 2-8.

Figure 2-8. Applying skins


Listing 2-14. Sample skin file for use in a theme

<%-- File: Day.skin --%> <asp:button runat="server" borderstyle="Solid"             borderwidth="2px" bordercolor="#66ff66"             backcolor="#99ffff" /> <asp:calendar runat="server" borderstyle="Solid"               borderwidth="2px" bordercolor="#66ff66"               backcolor="#99ffff" /> <asp:TextBox runat="server" backcolor="#99ffff" forecolor="#FF3333" /> 

The combination of stylesheets, skin files, and local image references means that themes encapsulate most of the common user interface elements you work with when building Web applications. The ability to group all of these elements together into one location that can be replicated and altered as desired is a powerful feature. Even if you don't plan on using themes as a way of "skinning" your application, the ability to isolate all of these files in one location with support for applying them across your entire site is reason enough to begin using themes.

Figure 2-9 shows a complete picture of how themes consolidate all of these elements together. The theme shown consists of a .css file, a .skin file containing formatting for a Calendar control, and an /images directory. When the page is constructed on the server, the theme is applied and the Calendar control inherits the styles defined by the Calendar control in the MyTheme.skin file. This process all happens on the server as the page and its controls are constructed. Note how the stylesheet (MyTheme.css) is implicitly added using a text/css link element in the <head> portion of the rendered page. Also note that the style attributes applied to the Calendar control impact the rendering of the Calendar as a <table> element to the client.

Figure 2-9. Theme application


Working with Themes

At this point you might be wondering, "What happens if a page to which a theme is applied has already defined attributes for a control that is specified in a .skin file of the theme?" It actually depends on how the theme is applied. If you use the standard Theme attribute on an @Page directive to apply the theme, the attributes for a control defined in a skin file are applied on top of any attributes defined locally. That is, attributes defined in the theme override attributes defined locally, and in general the two sets of attributes are merged. This can lead to some interesting results if you're not careful, since the designer of the page may not have anticipated that a theme would be augmenting and overriding properties she had defined.

The alternative way to apply a theme to a page is to use the StyleSheetTheme attribute instead. Applying a theme with this attribute will not override local values, and is so named because it behaves more like CSS stylesheets do with HTML elementsthey define properties that are applied if no other property has been defined. For example, to apply our Day theme via the StyleSheetTheme attribute, we could write:

<%@ Page StyleSheetTheme="Day" %> 


You can also define multiple skins for a single control in a .skin file if you use the SkinID attribute. This is a convenient way to create an alternate appearance for a particular control and have controls select the skin by using the same SkinID attribute when declared on a page, in much the same way you might define a class attribute for an HTML element to apply the attributes of a stylesheet class. Note that if a control on a page does not specify a SkinID attribute, it will always use the default skin (the one without any SkinID attribute in the .skin file). Listing 2-15 shows a sample .skin file that contains two skins for the TextBox control.

Listing 2-15. Using SkinID to create multiple control skins

<!-- FallTheme.skin --> <asp:TextBox runat="server" backcolor="DarkRed" /> <asp:TextBox runat="server" backcolor="DarkRed"              Font-StrikeOut="true" Skin /> 

Much like master pages, themes can be applied globally by using the pages element in your configuration file:

<!-- file: web.config --> <configuration>   <pages theme="Day" /> </configuration> 


You can also exempt a particular control from having a theme applied to it by using the EnableTheming="false" attribute. Pages can exempt themselves from any global theme application with the same attribute.

Also like master pages, themes can be set programmatically in the PreInit event of the Page class. It is even more likely that you will want to set the theme of a page programmatically, especially if you have created multiple themes and want to let users choose the look and feel of the site themselves.

Listing 2-16 shows an example of setting the theme programmatically in a page. Note that this is really the only place to set a theme; there is no built-in way to programmatically set the theme for an entire site. Unfortunately, this is often what is needed, so it is worth looking at how to accomplish setting the theme globally in code. One way is to create a common base Page-derived class that all of your pages inherit from and set the theme in the PreInit handler of that class. Another way is to trap the PreRequestHandlerExecute event in your HttpApplication class and add a handler to the PreInit event to set the theme there. Listing 2-17 shows an example of this latter technique using the global.asax file.

Listing 2-16. Changing a theme at runtime

protected override void OnPreInit(EventArgs e) {   this.Theme = "Night";   base.OnPreInit(e); } 

Listing 2-17. Changing the theme globally at runtime

<%--File: Global.asax--%> <%@ Application Language="C#" %> <script runat="server">     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)     {         // Note that you could retrieve the theme from         // anywhere at this point (most likely Profile as shown here).         //         Page p = this.Context.Handler as Page;         if (p != null) {           p.Theme = (string)Context.Profile["theme"];       }     } </script> 




Essential ASP. NET 2.0
Essential ASP.NET 2.0
ISBN: 0321237706
EAN: 2147483647
Year: 2006
Pages: 104

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net