Working with Themes

 

Working with Themes

For years, CSS styles have helped site developers to easily and efficiently design pages with a common and consistent look and feel. Although page developers can select the CSS file programmatically on the server, at its core CSS remains an inherent client-side technology, devised and implemented to apply skins to HTML elements. When you build ASP.NET pages, though, you mostly work with server controls.

CSS styles can be used to style server controls, but they're not the right tool for the job. The main issue here is that ASP.NET controls can have properties that are not the direct emanation of a CSS style property. The appearance of an ASP.NET control can be affected by an array of resources images, strings, templates, markup, combinations of various CSS styles. To properly apply skins to ASP.NET server controls, CSS files are necessary but not sufficient. Enter ASP.NET themes.

ASP.NET themes are closely related to Windows XP themes. Setting a theme is as simple as setting a property, and all the settings the theme contains are applied in a single shot. Themes can be applied to individual controls and also to a page or an entire Web site.

Warning 

Themes are a specific feature of ASP.NET 2.0. There's no built-in support for themes in ASP.NET 1.x. I discussed how to build a theme infrastructure for ASP.NET 1.x in the June 2004 issue of MSDN Magazine. The article is online at http://msdn.microsoft.com/msdnmag/issues/04/06/CuttingEdge.

Understanding ASP.NET Themes

In ASP.NET 1.x, when you author a page you don't just focus on the tasks a certain set of controls must be able to accomplish. You also consider their appearance. Most of the time, you end up setting visual attributes such as colors, font, borders, and images. The more sophisticated the control, the more time you spend making it look nice rather than just functional.

In ASP.NET 1.x, the DataGrid control one of the most popular and customizable controls provides a gallery of predefined styles from which you choose the most appealing. This gallery of predefined styles is the DataGrid's auto-format feature. DataGrid's built-in styles are implemented through a set of predefined settings that Visual Studio .NET 2003 applies to the control at design time. The auto-format feature saves testing and typing and lets you choose the style visually. Added as a time-saving feature, auto-format addresses the issue only partially, as it has two main drawbacks. First, a lot of visual attributes are still persisted to the .aspx source file, making rich pages hard to read and maintain. Second, the list of available formats is closed and can't be further extended or personalized.

Wouldn't it be great if you could compose your pages just by picking controls off the toolbox and connecting them, without even bothering about their final look? Wouldn't it be nice if you could then simply create an additional file in the project to define visual attributes for each type of control? In this way, the .aspx source file would be free of verbose visual attributes, and you could change the style of controls at will while performing few or no modifications to the original page. ASP.NET themes provide exactly this capability.

What's a Theme, Anyway?

A theme is a set of skins and associated files such as style sheets and images a sort of super CSS file. Once enabled, the theme determines the appearance of all controls under its jurisdiction. Consider the following simple markup:

<asp:Calendar  runat="server" /> 

Without themes, the calendar will look spare and spartan. With a theme added, the same markup renders a more colorful and appealing calendar. As you can see, a neat separation exists between the page contents and formatting rules. Look at Figure 6-9. Which do you think is the unthemed calendar?

image from book
Figure 6-9: The same controls, with and without themes.

To fully understand ASP.NET themes, you must be familiar with a few terms, which are detailed in Table 6-3.

Table 6-3: ASP.NET Themes Terminology

Term

Definition

Skin

A named set of properties and templates that can be applied to one or more controls on a page. A skin is always associated with a specific control type.

Style sheet

A CSS or server-side style sheet file that can be used by pages on a site.

StyleSheet Theme

A theme used to abstract control properties from controls. The application of this theme means that the control can still override the theme.

Customization Theme

A theme used to abstract control properties from controls, but the theme overrides the control and any style sheet theme.

Imagine you are creating a new Web site and would like it to be visually appealing from the start. Instead of having to learn all the available style properties of each employed control, you just use ASP.NET themes. Using a built-in theme in a page is as easy as setting a property, as we'll see in a moment. With this change, pages automatically inherit a new and, one hopes, attractive appearance. For example, if you add a Calendar control to a page, it automatically renders with the default appearance defined in the theme.

Selecting a theme for one or more pages doesn't necessarily bind you to the settings of that theme. Through the Visual Studio .NET designer, you can review the pages and manually adjust some styles in a control if you want to.

Note 

The following convention holds true in this book and, in general, in related literature. Unless otherwise suggested by the context, the word theme indicates a customization theme. A style sheet theme is usually referred to as a style sheet theme.

Structure of a Theme

Themes are expressed as the union of various files and folders living under a common root directory. Themes can be global or local. Global themes are visible to all Web applications installed on a server machine. Local themes are visible only to the application that defines them. Global themes are contained in child directories located under the following path. The name of the directory is the name of the theme:

%WINDOWS%\Microsoft.NET\Framework\[version]\ASP.NETClientFiles\Themes 

Local themes are specialized folders that live under the App_Themes folder at the root of the application. Figure 6-10 shows a sample theme (named ProAspNet20) in a Web application.


Figure 6-10: A view of this book's companion code's official theme in Visual Studio .NET 2005.

As you can see, the theme in the figure consists of a .css file and a .skin file. Generally, themes can contain a mix of the following resources:

The content types just listed are not exhaustive, but they do cover the most commonly used data you might want to store in a theme. You can have additional subdirectories filled with any sort of data that makes sense to skinned controls. For example, imagine you have a custom control that displays its own user interface through the services of an external ASP.NET user control (.ascx). Skinning this control entails, among other things, indicating the URL to the user control. The user control becomes an effective part of the theme and must be stored under the theme folder. Where exactly? That depends on you, but opting for a Controls subdirectory doesn't seem to be a bad idea. We'll return to this point later when building a sample theme.

Customization Themes vs. Style Sheet Themes

There are two forms of themes customization themes and style sheet themes. Customization themes are used for post-customization of a site. The theme overrides any property definition on the control found in the .aspx source. By changing the page's theme, you entirely modify the appearance of the page without touching the source files. If you opt for customization theming, you just need minimal markup for each control in the ASP.NET page.

Style sheet themes are similar to CSS style sheets, except that they operate on control properties rather than on HTML element styles. Style sheet themes are applied immediately after the control is initialized and before the attributes in the .aspx file are applied. In other words, with a style sheet theme developers define default values for each control that are in fact overridden by settings in the .aspx source.

Important 

Customization themes and style sheet themes use the same source files. They differ only in how the ASP.NET runtime applies them to a page. The same theme can be applied as a customization theme or a style sheet theme at different times.

The difference between customization and style sheet themes is purely a matter of which takes priority over which. Let's review the resultant form of a control when a customization theme and style sheet theme are applied. Imagine you have the following markup:

<asp:Calendar  runat="server" backcolor="yellow" /> 

If the page that contains this markup is bound to a customization theme, the calendar shows up as defined in the theme. In particular, the background of the calendar will be of the color defined by the theme.

If the page is bound to a style sheet theme, instead, the background color of the calendar is yellow. The other properties are set in accordance with the theme.

Theming Pages and Controls

You can apply themes at various levels application, folder, and individual pages. In addition, within the same theme you can select different skins for the same type of control.

Setting a theme at the application level affects all the pages and controls in the application. It's a feature you configure in the application's web.config file:

<system.web>     <pages theme="ProAspNet20" /> </system.web> 

The theme attribute sets a customization theme, while the styleSheetTheme attribute sets a style sheet theme. Note that the case is important in the web.config's schema. Likewise, a theme can be applied to all the pages found in a given folder and below that folder. To do so, you create a new web.config file in an application's directory and add the section just shown to it. All the pages in that directory and below it will be themed accordingly. Finally, you can select the theme at the page level and have styles and skins applied only to that page and all its controls.

Enabling Themes on a Page

To associate a theme with a page, you set the Theme or StyleSheetTheme attribute on the @Page directive, and you're all set:

<% @Page Language="C#" Theme="ProAspNet20" %> <% @Page Language="C#" StyleSheetTheme="ProAspNet20" %> 

Also in this case, Theme sets a customization theme, whereas StyleSheetTheme indicates a style sheet theme.

Bear in mind that the name of the selected theme must match the name of a subdirectory under the App_Themes path or the name of a global theme. If a theme with a given name exists both locally to the application and globally to the site, the local theme takes precedence. Figure 6-11 shows IntelliSense support for themes in Visual Studio .NET 2005.

image from book
Figure 6-11: IntelliSense support for themes in Visual Studio .NET 2005.

While we're speaking of precedence, it is important to note that themes have a hierarchical nature: directory-level themes takes precedence over application-level themes, and page-level themes override any other themes defined around the application. This hierarchy is independent of which attributes are used Theme or StyleSheetTheme to enable theming.

Note 

Setting both Theme and StyleSheetTheme attributes is not prohibited, though it is not a recommended practice. There's a behavioral gap between the two forms of themes that should make clear which one you need in any situation. However, if you set both attributes, consider that both themes will be applied first the style sheet theme and then the customization theme. The final results depend on the CSS cascading mechanism and ultimately are determined by the CSS settings of each theme.

Applying Skins

A skin file looks like a regular ASP.NET page as it is populated by control declaration and import directives. Each control declaration defines the default appearance of a particular control. Consider the following excerpt from a skin file:

<!-- This is a possible skin for a Button control --> <asp:Button runat="server"     BorderColor="darkgray"     Font-Bold="true"     BorderWidth="1px"     BorderStyle="outset"     ForeColor="DarkSlateGray"     BackColor="gainsboro" /> 

The net effect of the skin is that every Button control in a themed page will be rendered as defined by the preceding markup. If the theme is applied as a style sheet, the settings just shown will be overridable by the developer; if the theme is a customization theme, those settings determine the final look and feel of the control. Properties that the theme leave blank are set according to the control's defaults or the .aspx source.

Important 

Whatever theme you apply customization or style sheet control properties can always be modified through code in page events such as Init and Load.

A theme can contain multiple skins for a given control, each identified with a unique name the SkinID attribute. When the SkinID attribute is set, the skin is said to be a named skin. A theme can contain any number of named skins per control, but just one unnamed (default) skin. You select the skin for a control in an ASP.NET themed page by setting the control's SkinID property. The value of the control's SkinID property should match an existing skin in the current theme. If the page theme doesn't include a skin that matches the SkinID property, the default skin for that control type is used. The following code shows two named skins for a button within the same theme:

<!-- Place these two definitions in the same .skin file --> <asp:button skin BackColor="gray" /> <asp:button skin BackColor="lightcyan" /> 

When you enable theming on a page, by default all controls in that page will be themed except controls, and individual control properties, that explicitly disable theming.

Note 

The automatic application of themes to all controls in a page makes it easy to customize a page that has no knowledge of skins, including existing pages written for ASP.NET 1.x.

Taking Control of Theming

The ASP.NET 2.0 theming infrastructure provides the EnableTheming Boolean property to disable skins for a control and all its children. You can configure a page or control to ignore themes by setting the EnableTheming property to false. The default value of the property is true. EnableTheming is defined on the Control class and inherited by all server controls and pages. If you want to disable theme support for all controls in a page, you can set the EnableTheming attribute on the @Page directive.

Important 

Note that the EnableTheming property can be set only in the Page_PreInit event for static controls that is, controls defined in the .aspx source. For dynamic controls controls created programmatically you must have set the property before adding the control to the page's control tree. A control is added to the page's control tree when you add to the Controls collection of the parent control typically, the form or another control in the form.

When is disabling themes useful? Themes are great at ensuring that all page controls have a consistent look and feel, but at the same time themes override the visual attributes of any control for which a skin is defined. You can control the overriding mechanism a bit by switching style sheet and customization themes. However, when you want a control or page to maintain its predefined look, you just disable themes for that page or control.

Note that disabling themes affects only skins, not CSS styles. When a theme includes one or more CSS style-sheet files, they are linked to the <head> tag of the resulting HTML document and, after that, are handled entirely by the browser. As you can easily guess, there's not much a Web browser can know about ASP.NET themes!

Theming Controls

Themes style server controls to the degree that each control allows. By default, all control properties are themeable. Theming can be disabled on a particular property by applying the Themeable attribute on the property declaration, as follows:

[Themeable(false)] public virtual bool CausesValidation {     get {   }     set {   } } 

You can't change the Themeable attribute for built-in server controls. You have that option for custom controls instead. Moreover, for custom controls you should use the Themeable attribute to prevent theming of behavioral properties such as the CausesValidation property just shown. Themes should be used only on visual properties that uniquely affect the appearance of the control:

[Themeable(false)] public MyControl : Control {     ... } 

Finally, the Themeable attribute can be applied to the class declaration of a custom control to stop it from ever bothering about themes.

Putting Themes to Work

Finding a bunch of themes that suit your needs, free or for a small fee, shouldn't be a problem. However, this is a bad reason for not learning how to build your own themes. As mentioned, themes consist of several supporting files, including CSS style sheets and control skins to decorate HTML elements and server controls, respectively, and any other supporting images or files that make up the final expected result.

I firmly believe that building nice-looking, consistent, usable themes is not a programmer's job. It is a task that designers and graphics people can easily accomplish ten times better and faster. However, themes are more than CSS files, and what's more, they are in the area of control properties exactly the realm of the developer. In short, developers should provide guidance to theme designers much more than we did in the past with CSS authors.

As a first step, let's review the key differences between CSS files and themes.

CSS vs. Themes

Themes are similar to CSS style sheets in that both apply a set of common attributes to any page where they are declared. Themes differ from CSS style sheets in a few key ways, however.

First and foremost, themes work on control properties, whereas CSS style sheets operate on styles of HTML elements. Because of this, with themes you can include auxiliary files and specify standard images for a TreeView or Menu control, the paging template of a DataGrid, or the layout of a Login control. In addition, themes can optionally force overriding of local property values (customization themes) and not cascade as CSS style sheets do.

Because themes incorporate CSS style-sheet definitions and apply them along with other property settings, there's no reason for preferring CSS style sheets over themes in ASP.NET 2.0 applications.

Creating a Theme

To create a new theme in a Visual Studio .NET 2005 solution, you start by creating a new folder under App_Themes. The simplest way to do this is by right-clicking the App_Themes node and selecting a theme folder. Next, you add theme files to the folder, and, when you're done, you can even move the entire directory to the root path of global themes on the Web server.

Typical auxiliary files that form a theme are listed in Figure 6-12. They are CSS style-sheet files, skin files, XML or text files, and extensible style-sheet files (XSLT). Empty files of the specified type are created in the theme folder and edited through more or less specialized text editors in Visual Studio .NET 2005.

image from book
Figure 6-12: Adding auxiliary files to an ASP.NET theme.

A skin file is a collection of a control's markup chunks, optionally named through the SkinID attribute. You can create a skin file by cutting and pasting the markup of controls you visually configured in a sample page. If some properties of the skinned controls require resources, you can point them to a path inside the theme folder. Here's an example:

<asp:BulletedList runat="server"     Font-Names="Verdana"     BulletImageURL="Images/smokeandglass_bullet2.gif"     BulletStyle="CustomImage"     BackColor="transparent"     ForeColor="#585880" /> 

This skin of the BulletedList control points to a theme-specific URL for the bullet image. The directory Images is intended to be relative to the theme folder. Needless to say, the name Images is totally arbitrary. Should the skin require other external files, you could group them in other theme subdirectories.

A skin file can define the appearance of built-in server controls as well as custom controls. To skin a custom control, though, you must first reference it in the file, as follows:

<%@ Register TagPrefix="expo"              Namespace="Expoware.ProAspNet20.Controls"              Assembly="ProAspNet20.Controls" %> 

Next, you add the desired default markup for any control defined in the specified assembly and namespace.

Loading Themes Dynamically

You can apply themes dynamically, but this requires a bit of care. The ASP.NET runtime loads theme information immediately after the PreInit event fires. When the PreInit event fires, the name of any theme referenced in the @Page directive is already known and will be used unless it is overridden during the event. If you want to enable your users to change themes on the fly, you create a Page_PreInit event handler. The following code shows the code file of a sample page that changes themes dynamically:

public partial class TestThemes : System.Web.UI.Page {     protected void Page_Load(object sender, EventArgs e)     {         if (!IsPostBack) {             ThemeList.DataSource = GetAvailableThemes();             ThemeList.DataBind();         }     }     void Page_PreInit(object sender, EventArgs e)     {         string theme = "";         if (Page.Request.Form.Count > 0)             theme = Page.Request["ThemeList"].ToString();         if (theme == "None")             theme = "";         this.Theme = theme;     }     protected StringCollection GetAvailableThemes()     {         string path = Request.PhysicalApplicationPath + @"App_Themes";         DirectoryInfo dir = new DirectoryInfo(path);         StringCollection themes = new StringCollection();         foreach (DirectoryInfo di in dir.GetDirectories())             themes.Add(di.Name);         return themes;     } } 

Figure 6-13 shows the page in action. The drop-down list control enumerates the installed application themes and lets you choose the one to apply. The selected theme is then applied in the PreInit event and immediately reflected. In the PreInit event, no view state has been restored yet; Request.Form is the only safe way to access a posted value like the selected theme.

image from book
Figure 6-13: Changing themes dynamically in a sample page.

 


Programming Microsoft ASP. Net 2.0 Core Reference
Programming Microsoft ASP.NET 2.0 Core Reference
ISBN: 0735621764
EAN: 2147483647
Year: 2004
Pages: 112
Authors: Dino Esposito
BUY ON AMAZON

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