An
ASP.NET Theme enables you to apply a consistent style to the pages in
your website. You can use a Theme to control the appearance of both the
HTML elements and ASP.NET controls that appear in a page. Themes are
different than Master Pages. A Master Page enables you to share content
across multiple pages in a website. A Theme, on the other hand, enables
you to control the appearance of the content.
In
this chapter, you learn how to create and apply ASP.NET Themes. First,
you learn how to create Skins. A Skin enables you to modify the
properties of an ASP.NET control that have an effect on its appearance.
You learn how to create both Default and Named Skins.
Next,
you learn how to format both HTML elements and ASP.NET controls by
adding Cascading Style Sheets to a Theme. Cascading Style Sheets enable
you to control the appearance and layout of pages in a website in a
standardscompliant manner.
You
also learn how you can create Global Themes, which can be used by
multiple applications located on the same server. You learn how to use
Global Themes with both File System and HTTP-based websites. Finally,
you learn how to load Themes and Skins dynamically at runtime. You build
a page that each user of a website can customize by skinning.
Creating Themes
You
create a Theme by adding a new folder to a special folder in your
application named App_Themes. Each folder that you add to the App_Themes
folder represents a different Theme. If the App_Themes folder doesn’t
exist in your application, then you can create it. It must be located in
the root of your application.
VISUAL WEB DEVELOPER NOTE
When
using Visual Web Developer, you can create a new Theme folder by
right-clicking the name of your project in the Solution Explorer window
and selecting Add Folder, Theme Folder.
A
Theme folder can contain a variety of different types of files,
including images and text files. You also can organize the contents of a
Theme folder by adding multiple subfolders to a Theme folder.
The most important types of files in a Theme folder are the following:
Skin files
Cascading Style Sheet files
In the following sections, you learn how to add both Skin files and Cascading Style Sheet
files to a Theme.
WARNING
Be
careful about how you name your Theme (the folder name). The contents
of a Theme folder are automatically compiled in the background into a
new class. So you want to be careful not to name a Theme with a class
name that conflicts with an existing class name in your project.
Adding Skins to Themes
A
Theme can contain one or more Skin files. A Skin enables you to modify
any of the properties of an ASP.NET control that have an effect on its
appearance. For example, imagine that you decide that you want every
TextBox control in your web application to appear with a yellow
background color and a dotted border. If you add the file in Listing 6.1
to the Simple Theme (the App_Themes\Simple folder), then you can modify
the appearance of all TextBox controls in all pages that use the Simple
Theme.
Notice
that the Skin file in Listing 6.1 is named TextBox.skin. You can name a
Skin file anything you want. I recommend following a naming convention
in which you name the Skin file after the name of the control that the
Skin modifies.
A
Theme folder can contain a single Skin file that contains Skins for
hundreds of controls. Alternatively, a Theme can contain hundreds of
Skin files, each of which contains a single Skin. It doesn’t matter how
you organize your Skins into files because everything in a Theme folder
eventually gets compiled into one Theme class.
The
Skin file in Listing 6.1 contains a declaration of a TextBox control.
Notice that the TextBox control includes a BackColor property that is
set to the value Yellow and a BorderStyle property that is set to the
value Dotted. You should notice that the TextBox control includes a
Runat=”Server” attribute, but it does not include an ID attribute. You
must always include a Runat attribute, but you can never include the ID
attribute when declaring a control in a Skin.
NOTE
You
can’t create a Skin that applies to the properties of a User control.
However, you can Skin the controls contained inside a User control. The
Skin is applied to every page to which the Simple Theme is applied. For
example, the page in Listing 6.2 uses the Simple Theme.
Notice
that the page in Listing 6.2 includes a Theme attribute in its <%@
Page %> directive. This attribute causes the Simple Theme to be
applied to the page. When you open the page in Listing 6.2, the Label
control appears with a yellow background color and dotted border. This
is the background color and border specified by the Theme (see Figure
6.1).
Only
certain control properties are “themeable.” In other words, you can
create a Skin file that modifies only certain properties of a control.
In general, you can use a Skin to modify properties that have an effect
on a control’s appearance but not its behavior. For example, you can
modify the BackColor property of a TextBox control but not its
AutoPostBack property.
Themes Versus StyleSheetThemes
When
you apply a Theme to a page, the Skins in the Theme override any
existing properties of the controls in the page. In other words,
properties in a Skin override properties in a page. For example, imagine
that you create the Skin in Listing 6.5.
The
page in Listing 6.6 includes a Label that has a BackColor property
which is set to the value Red. However, when you open the page, the
BackColor declared in the Skin overrides the BackColor declared in the
page and the Label is displayed with an orange background.
The
default behavior of Themes makes it very easy to modify the design of
an existing website. You can override any existing control properties
that have an effect on the appearance of the control.
However,
there are situations in which you might want to override Skin
properties. For example, you might want to display every Label in your
website with an orange background color except for one Label. In that
case, it would be nice if there was a way to override the Skin property.
You can override Skin properties by applying a Theme to a page with the
StyleSheetTheme attribute instead of the Theme attribute. For example,
the page in Listing 6.7 uses the StyleSheetTheme attribute to apply the
Simple3 Theme to the page.
Notice
that the <%@Page %> directive in Listing 6.7 includes a
StyleSheetTheme attribute. When you open the page in Listing 6.7 in a
web browser, the Label is displayed with a red background color instead
of the orange background color specified by the Theme.
Registering Themes in the Web Configuration File
Rather
than add the Theme or StyleSheetTheme attribute to each and every page
to which you want to apply a Theme, you can register a Theme for all
pages in your application in the web configuration file. The Web.Config
file in Listing 6.10 applies the Site Theme to every page in an
application.
Rather
than use the theme attribute, you can use the styleSheetTheme attribute
to apply a Theme to the pages in an application. If you use the
styleSheetTheme attribute, you can override particular Skin properties
in a page. The web configuration file in Listing 6.11 includes the
styleSheetTheme attribute.
After
you enable a Theme for an application, you can disable the Theme for a
particular page by using the EnableTheming attribute with the <%@
Page %> directive. For example, the page in Listing 6.12 disables any
Themes configured in the web configuration file.
Adding Cascading Style Sheets to Themes
As
an alternative to Skins, you can use a Cascading Style Sheet file to
control the appearance of both the HTML elements and ASP.NET controls
contained in a page. If you add a Cascading Style Sheet file to a Theme
folder, then the Cascading Style Sheet is automatically applied to every
page to which the Theme is applied. For example, the Cascading Style
Sheet in Listing 6.13 contains style rules that are applied to several
different HTML elements in a page.
If
you add the SimpleStyle.css file to a Theme named StyleTheme (a folder
named StyleTheme in the App_Themes folder), then the Cascading Style
Sheet is applied automatically to the page in Listing 6.14.
The
Cascading Style Sheet is used to style several HTML elements in Listing
6.14 (see Figure 6.4). For example, the Style Sheet sets the background
color of the page to the value Gray. It also centers the <div>
tag containing the page content.
Because
an ASP.NET control renders HTML, the Style Sheet also styles the HTML
rendered by the ASP.NET Label, TextBox, and Button controls. An ASP.NET
Label control renders an HTML <label> tag and the Style Sheet
formats all <label> tags in bold. Both a TextBox control and a
Button control render HTML <input> tags. The Style Sheet modifies
the border and background color of the <input> tag.
Notice
that the Button control includes a CssClass attribute. By providing a
control with a CssClass attribute, you can target a particular control
(or set of controls) in a Cascading Style Sheet. In this case, the
background color of the <input> tag rendered by the Button control
is set to the value #eeeeee (light gray).
I
recommend that you do all your web page design by using the method
discussed in this section. You should place all your page design in an
external Cascading Style Sheet located in a Theme folder. In particular,
you should not modify the appearance of a control by modifying its
properties. Furthermore, you should avoid using Skin files.
The
advantage of using Cascading Style Sheets is that they result in leaner
and faster loading pages. The more content that you can place in an
external Style Sheet, the less content must be loaded each time you make
a page request. The contents of an external Style Sheet can be loaded
and cached by a browser and applied to all pages in a web application.
If,
on the other hand, you modify the appearance of a control by modifying
its properties, then additional content must be rendered to the browser
each time you make a page request. For example, if you modify a Label
control’s BackColor property, then an additional Style attribute is
rendered when the Label control is rendered. Using Skins is no different
than setting control properties. Skins also result in bloated pages.
For example, if you create a Skin for a Label control, then the
properties of the Label Skin must be merged with each Label control on
each page before the Label is rendered.
Applying Themes Dynamically
You
might want to enable each user of your website to customize the
appearance of your website by selecting different Themes. Some website
users might prefer a green Theme and
other
website users might prefer a pink Theme. You can dynamically apply a
Theme to a page by handling the Page PreInit event. This event is the
first event that is raised when you request a page. You cannot apply a
Theme dynamically in a later event such as the Page Load or PreRender
events. For example, the page in Listing 6.18 applies either the green
Theme or the pink Theme to the page depending on which link you click in
the page body (see Figure 6.8).
A
particular Theme is applied to the page with the help of the Theme
property. You can assign the name of any Theme (Theme folder) to this
property in the Page PreInit event, and the Theme will be applied to the
page.
Notice
that the selected Theme is stored in the Profile object. When you store
information in the Profile object, the information is preserved across
multiple visits to the website. So, if a user selects a favorite Theme
once, the Theme is applied every time the user returns to the website in
the future.
The Profile is defined in the web configuration file in Listing 6.19.
















