Overriding Themes
Earlier, we mentioned
how a skin will overwrite any display properties we set on a control in our
ASPX page. There might be times when this is not the desired behavior. One way
to avoid the application of skin properties is to disable themeing for a
specific control (or for an entire page) by setting the enable themeing
property to false.
<asp:Label
runat="server" ID="label1"
Text="Hello, from OdeToCode"
ForeColor="Green" EnableTheming="false" />
The EnableThemeing
property will cascade through child controls. For instance, if you set
EnableThemeing=false on a Panel or user control, any control inside of the
panel or user control will not be themed.
A second way to use
individual control properties is by specifying a StyleSheetTheme instead of a
Theme. Unlike the properties applied by a Theme, the properties applied by a
StyleSheetTheme can be overridden in a page. In the following webform, the
first Label will display with the BlueViolet color of the Odeish theme, while
the second label will override the skin setting and display with a DarkSalmon
color.
<%@
Page Language="C#" AutoEventWireup="true"
CodeFile="Default4.aspx.cs" Inherits="Default4"
StylesheetTheme="Odeish" %>
<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml" >
<head
runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" ID="label1"
Text="Hello World" />
<asp:Label runat="server" ID="label2"
Text="Hello World"
ForeColor="DarkSalmon"/>
</div>
</form>
</body>
</html>
Just to be clear: if
we had specified a Theme instead of a StyleSheetTheme, both labels would
display with the BlueViolet color. If we were to specify a Theme for our pages
in web.config, the web.config Theme setting would override this StyleSheetTheme
and both Labels would display in BlueViolet.
Interesting note: the
Visual Studio designer will display the form with the skins applied when a
StyleSheetTheme is in effect. The designer does not apply skins when a Theme is
in effect.
Themes and CSS Style Sheets
Themes and CSS files
can work together to control the look of your application. You can add one or
more .css files into a theme directory. ASP.NET will automatically apply all of
a theme’s style sheets into a page by injecting a <link> element for each
.css into the header of a page. Your page must have runat=”server” in the
<head%gt; tag for the automatic style sheet inclusion. The pages created by
the IDE have this setting automatically.
For instance, we can
control the background color of our page using the following style sheet.
body
{
background-color:Gray;
}
Obviously, style
sheets and skins have some overlap. For instance we could use a skin to set the
ForeColor of our label, or we could have used a CSS class to set the color of
our label text (perhaps by setting the CssClass property of the label with a
skin).
Here are some points
to consider when deciding on a skin file versus a style sheet entry.
- Web designers will be more comfortable with css files.
If you put the design of your site into the hands of professionals than
you should be asking them to use css wherever possible. This will allow
you to just drop new and updated css files into the theme folders and be
ready to go.
- Developers might be more comfortable with skins. Since
skins look just like a control declaration, a developer will have an easy
time creating a skin file. There is also no need to know in advance what
HTML a complex server-side web control will produce in order to write the
correct class and styles.
- Skins are applied server-side and can set more than
just style related properties. For example, in our Calendar.skin example
we were able to set a default for the DayNameFormat for all calendar
controls using the theme.
- Likewise, you can control some areas with CSS (like the
body element above) with style sheets and not skins
- While the settings in a style sheet cascade, the
properties in a skin are absolute, i.e. you can override a style sheet
with a local setting but not a skin (unless you take one of the steps
outlined in this article).
- Different browsers may react to style sheets in
different ways. You can count on skin files to always apply their
properties to controls consistently on the server (it’s up to ASP.NET to
translate those settings into the correct settings for the client).
Themes with Images
You can also include
images in the themes directories. Images inside of themes are particularly
useful for controls like the TreeView, and Menu controls that rely on
consistent but customizable images to render themselves.
All you need to do is
provide your skin with a relative URL to the image. ASP.NET will take care of
fixing up the URLs.
Under The Hood
When a request arrives
for an ASP.NET 2.0 site, the runtime will parse and compile the App_Themes
directory into assemblies. Although we might not think of a theme as being
“code” (nor may a theme or skin file actually contain any code) – the runtime
does turn each theme definition into code inside an assembly.
Each assembly will
contain a class representing the theme – this class will derive from
System.Web.UI.PageTheme. The class will contain a LinkedStyleSheets property
that returns an array of string – the filenames for the styles of the theme.
The class will also
maintain a dictionary data structure. The key into the dictionary is a type
(like typeof(Label) and typeof(Calendar). Given the key, the dictionary will
return a ControlSkinDelegate. The delegate is a pointer to the method that
“builds” a control according to the rules in a skin file. For example, the skin
file for our label produced the following method.
private Control
__BuildControl__control11(Control ctrl)
{
Label label1 = (Label) ctrl;
label1.ForeColor = Color.BlueViolet;
return label1;
}
When the runtime sees
that a page has a theme, it walks through the Controls array of the page and
checks to see if there is a delegate available to skin the control based on the
type of the control. If an entry exist, the runtime will invoke the delegate,
which in the case of a Label in an Odeish page theme will execute the above
code.
Themes and Master Pages
As we alluded to
earlier in the article, there can be some overlap between themes and master
pages. In the previous article we actually controlled the layout of our
application by defining <div>s in our master page and specifying the
layout of the <div>s in a .css file.
The above approach is
a viable approach when using themes. Push your layout defining css into the
themes folder for the ultimate power and flexibility. Your master pages will
continue to define the basic structural elements and common content for every
page.
No comments:
Post a Comment