Skip navigation

Author Once, Theme Always

Build ASP.NET Pages that Support Variable Graphics

CoreCoder

LANGUAGES: C# | VB.NET

ASP.NET VERSIONS: 2.0

 

Author Once, Theme Always

Build ASP.NET Pages that Support Variable Graphics

 

By Dino Esposito

 

There are controls in the ASP.NET framework that supply sophisticated user interface features. But finding the right combination of style settings and values for appearance properties can be difficult, even with the help of Visual Studio.NET designers. Only searching in the ASP.NET 1.x toolbox, you can find at least a couple of these UI-rich controls: DataGrid and Calendar. Aware of the issue, these controls attempt to alleviate your troubles by providing smart options in the Visual Studio.NET 2003 designer. These options manifest through the AutoFormat feature (a list of predefined skins for controls). This is nothing radically new AutoFormat was first introduced with Microsoft Word tables yet this is a useful and time-saving capability. To be really helpful, however, the auto-format feature would need at least a couple of additions, such as definition of custom skins and programmatic binding of skins.

 

In ASP.NET 2.0, both goals are achieved thanks to themes. Like AutoFormat, themes is not a new concept for Microsoft software products. Logically speaking, in fact, ASP.NET themes are in no way different from Windows XP themes. Themes are a feature for customizing the visual appearance of a Web page and, in turn, of the whole Web site. As a developer, you can define one or more themes to ship with your application; as a power user, you can customize the look-and-feel of a site by choosing one of the available themes.

 

There s some architectural work in the ASP.NET runtime to make support for themes possible. For this reason, themes are supported in ASP.NET 2.0, but not in ASP.NET 1.x. Themes are pluggable elements in any ASP.NET application so that third-party vendors can even create and sell themes for certain particularly rich controls.

 

In short, themes are an easy way for page authors to ensure a consistent look-and-feel for the constituent controls of a page. At the same time, themes let you easily change the appearance of a control in a single shot. Settings contained in a theme can be deployed to individual applications or all applications in a server with the same ease.

 

What Is a Theme, Anyway?

At its core, a theme makes it easy to customize the visual appearance of a Web site while requiring little or no modifications to the original page. Pages can seamlessly work with or without a theme and use different themes at different times based on user preferences. Technically speaking, a theme is a collection of files and can be overall seen as a sort of super CSS file.

 

A theme may include a CSS stylesheet file, as well as a set of skins and associated files such as images and other resources. Like a CSS, once enabled the theme determines the appearance of all controls that fall under its jurisdiction. To get the gist of themes, consider this simple tag:

 

 

Without themes, the calendar will look quite spartan. With a theme added, however, the same markup renders a more colorful and appealing calendar. Take a look at Figure 1. Which do you think is the unthemed calendar? To get a more appealing result, no code had to be added; a new attribute in the @Page directive does the trick. As you can see, themes supply a neat separation between the page code, controls, and formatting rules.

 


Figure 1: A Calendar control, with and without themes.

 

Central to themes is the concept of a skin. A skin is a named set of visual properties and templates that can be applied to one or more controls on a page. The skin determines the appearance of a control in much the same way clothes determine the appearance of people. A skin is always associated with a specific control type. In Beta 2, ASP.NET 2.0 doesn t ship any sample themes but writing one is a snap, as you ll see in a moment.

 

Stylesheet and Customization Themes

In ASP.NET 2.0 there are two types of themes, stylesheet themes and customization themes. What s the difference? They re the same kind of object; the difference lies in how they re managed by the ASP.NET runtime. A stylesheet theme is applied to the controls in the page before the attributes in the .aspx source file are processed. This means that settings in the .aspx file will override the settings defined by the theme. On the other hand, a customization theme is applied later and overrides any settings hard-coded in the .aspx source file. It is essential to note that whatever theme you apply, whether it be customization or stylesheet-control properties, it can always be modified through code in page events like Init and Load.

 

You set stylesheet themes and customization themes using different attributes in the @Page directive. The same theme can be used as a stylesheet or customization theme at different times.

 

Imagine you create a new Web site and you want it to be visually appealing from the start. Instead of having to learn all the available style properties of each employed control, you simply get a third-party ASP.NET theme (or have other members of your team create one). With this change, pages automatically inherit a new, and hopefully attractive, appearance. For example, if you add a Calendar control to a page, it automatically renders with the default appearance defined in the theme with no need for setting other properties declaratively or programmatically.

 

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

 

Create a Theme

To create a new theme in a Visual Studio.NET 2005 ASP.NET solution, you start by creating a new folder under App_Themes. Right-click on the App_Themes node and choose to create a theme folder. Next, you add theme files to the folder. In this way, you create a theme specific to the application. By moving the directory to the root path of global themes on the Web server you can make that theme available to all Web applications installed on the server machine. Figure 2 shows the contents of a sample theme as it appears through Windows Explorer. A theme is an aggregation of files. Typical auxiliary files are CSS stylesheet files, skin files, images, XML or text files, or extensible stylesheet files (XSLT). In Visual Studio.NET 2005 you can create any of these by adding a new item to the folder. Empty files of the specified type are created in the theme folder and edited through more or less specialized text editors. Of all the possible auxiliary files, skin files are the least known and, therefore, the only ones to deserve further attention in this article.

 


Figure 2: The constituent files of an ASP.NET theme.

 

Saved with a .skin extension, a skin file contains the theme-specific markup for a given set of controls. A skin file is made by a sequence of server control definitions that include predefined values for most visual properties, images for URL-based properties, and markup for supported templates. Each skin is control-specific and has a unique name. You can define multiple skins for a given control and distinguish them by name. Once themed, a control has the original markup written in the .aspx source file modified at run time by the content of the skin. The way the modification occurs depends on whether a customization or a stylesheet theme is used. Skin files are located in the root of the theme folder. Figure 3 shows a sample skin file.

 

 ForeColor="#585880" Font-Size="0.9em" Font-Names="Verdana" />

 BorderStyle="Solid" Font-Size="0.9em" Font-Names="Verdana"

 ForeColor="#585880" BorderColor="#585880" BorderWidth="1pt"

 CssClass="theme_textbox" />

 Font-Bold="true" BorderWidth="1pt" ForeColor="#585880"

 BackColor="#F8F7F4" />

 Font-Bold="true" BorderWidth="1pt" ForeColor="white"

 BackColor="red" />

Figure 3: A sample skin file.

 

In a page themed with the theme shown in Figure 3, the following markup will render buttons with bold font and a 1-pixel border:

 

 

Likewise, the textboxes will have a 1-pixel frame and white background. You have no need to bother about styles; you choose the theme you like, apply it, and go. But how do you apply a theme?

 

Apply a Theme

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, as follows:

 

 

 

The preceding theme attribute sets a customization theme. If you use the styleSheetTheme attribute instead, you set a stylesheet theme. Likewise, a theme can be applied to all the pages found in a given folder and below. To do that, you create a new web.config file in an application s directory and add to it the section shown above. You can also set the theme for a particular page. In this case, only the controls in the page will be themed. You set a customization or stylesheet theme using the Theme or StyleSheetTheme attribute on the @Page directive:

 

<% @Page Language="C#" Theme="SmokeAndGlass" %>

<% @Page Language="C#" StyleSheetTheme=

 "SmokeAndGlass" %>

 

It is important to note 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.

 

A theme can contain multiple skins for a given control, each identified with a unique name (the SkinID attribute). 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. If the page theme doesn t include a skin that matches the SkinID property, the default skin for that control type is used. Given the skin shown in Figure 3, only the second of the two buttons below will display with a red background:

 

 "Click" skinid="RedButton" />

 

When you enable theming on a page, all controls are themed except controls, and individual control properties, that explicitly disable theming. To disable theming, set the boolean EnableTheming property on ASP.NET 2.0 controls to false.

 

CSS vs. Themes

Themes are similar to CSS stylesheets in that both apply a set of common attributes to any page where they are declared. However, themes differ from CSS stylesheets in a few key ways. Themes work on control properties, whereas CSS stylesheets operate on styles of HTML elements. With themes you can include auxiliary files and specify standard images for particularly UI-rich controls, such as the TreeView control or the paging template of a DataGrid. In addition, themes can optionally force overriding of local property values (customization themes) and not cascade as CSS stylesheets do.

 

As themes incorporate CSS stylesheet definitions, and apply them along with other property settings, there s no reason for preferring CSS stylesheets over themes in ASP.NET 2.0 applications.

 

Load Themes Dynamically

Themes are normally defined statically and never change unless you edit the pages on the production server. However, themes could be applied and changed dynamically in pages that support this feature explicitly. The ASP.NET runtime loads theme information immediately after the PreInit event fires. When the PreInit event fires (this is a new event in the ASP.NET 2.0 page lifecycle) the Theme property of the Page class is set with any theme referenced in the @Page directive. By handling the event, you can programmatically override it. So if you want to enable your users to change themes on the fly, create a Page_PreInit event handler, as shown in Figure 4. Figure 5 shows the sample 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 viewstate has been restored yet; so Request.Form is the only safe way to access a posted value such as the selected theme.

 

(C#)

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;

 }

 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;

 }

}

(VB)

Public Partial Class TestThemes : Inherits System.Web.UI.Page

   Protected Sub Page_Load(ByVal sender As Object,

                           ByVal e As EventArgs)

 If Not IsPostBack Then

   ThemeList.DataSource = GetAvailableThemes()

   ThemeList.DataBind()

 End If

   End Sub

   Sub Page_PreInit(ByVal sender As Object,

                    ByVal e As EventArgs)

 Dim theme As String = ""

 If Page.Request.Form.Count > 0 Then

   theme = Page.Request("ThemeList").ToString()

 End If

 If theme = "None" Then

   theme = ""

 End If

 Me.Theme = theme

   End Sub

   Function GetAvailableThemes() As StringCollection

 Dim path As String = Request.PhysicalApplicationPath + _

                           "App_Themes"

 Dim dir As DirectoryInfo = New DirectoryInfo(path)

 Dim themes As New StringCollection

 For Each di As DirectoryInfo In dir.GetDirectories()

   themes.Add(di.Name)

 Next

 Return themes

   End Function

End Class

Figure 4: A page that lets users change the theme dynamically.

 


Figure 5: Changing themes dynamically.

 

Conclusion

ASP.NET themes let developers author pages and controls that users and designers can skin at will. Conceptually similar to Windows XP themes, ASP.NET themes can overall be seen as a superset of CSS style sheets that cover control properties in addition to HTML element styles. Themes work well in conjunction with another hot new feature of ASP.NET 2.0 the user profile API. Using both, developers can let end users choose the theme and persist its name back to the personalization storage layer so that the proper theme will be applied as the user reconnects. Incorporating superior functions in ASP.NET pages has never been this easy.

 

C# and VB.NET sample code accompanying this article is available for download.

 

Dino Esposito is a trainer and consultant who specializes in ASP.NET and ADO.NET. Author of Programming Microsoft ASP.NET and Introducing ASP.NET 2.0, both from Microsoft Press, Dino also helped several companies architect and build effective products for ASP.NET developers. Dino is the cofounder of http://www.DotNet2TheMax.com, a popular portal for .NET programmers. Write to him at mailto:[email protected] or join the blog at http://weblogs.asp.net/despos.

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish