ASP.NET 2.0 #1: Themes and Skins Sample

The skin of a graphical user interface is the element that determines how that interface looks, or, conversely, a graphical user interface has a skin to the extent that its appearance can be controlled by manipulating a single element.

The customary way of making it possible to control the appearance of a Web page by manipulating a single element is to use a style sheet to define how a page looks.

 

In the Cascading Style Sheets specification, there are classes with properties, and in the HTML specification, there are tags with attributes, and, in skinning our page using a cascading style sheet, we assign tags to classes, and then assign values to the properties of those classes, and that has the effect of setting the values of the tags’ attributes. Then one has to ask, if the skinning of our page is done by assigning values to the attributes of HTML tags indirectly by assigning values to the properties of style sheet classes, is there a style sheet property for every attribute of each HTML tag to which we might need to assign a value in defining our skin? The answer to that question is no: not all of the attributes of HTML tags to which we might want to assign a value in defining the skin of our page have corresponding Cascading Style Sheet properties by which the attributes can be assigned values. The SRC attribute of an IMG tag is one obvious example of an HTML attribute for which there is no corresponding Cascading Style Sheet property, one example of an HTML attribute to which a value cannot be assigned using a Cascading Style Sheet property. Thus, one limitation of Cascading Style Sheets is that the properties defined in the Cascading Style Sheet specification are a weirdly-truncated subset of the attributes defined in the HTML specification.

Cascading Style Sheets have one other important limitation: as for HTML and scripting there are various specifications, and browsers vary in the specifications that they support and the extent to which they support them. One of the most important features of the earlier versions of ASP.NET was their introduction of Web Form Controls, controls that would render themselves automatically using HTML and script appropriate for a user’s browser. Ironically, when ASP.NET debuted, Internet Explorer was at a peak of near universal adoption, which meant that Web Form Controls appeared at the point in history when they were least necessary. However, the recent success of the Mozilla Foundation’s Firefox browser has made it important once again to design Web pages to work properly in different kinds of browsers. So, it is especially timely that the new version of ASP.NET is introducing a browser-independent way of skinning one’s pages. This mechanism is called themes.

In the following example, the sources of three images in a page that are to be skin-specific are determined by a skin file in an ASP.NET 2.0 Theme folder. Once the stylesheet for the page is added to the Theme folder, then the page is truly skinned, with ALL of the skin of the page controlled via the contents of the Theme folder.

Themes\Basic\Basic.skin file:

<asp:Image runat="server" SkinID="Logo" src="/images/Saler/SalerLogo.gif"/>

<asp:Image runat="server" SkinID="RoundedEdgeTop" src="/images/Saler/ActivityHeaderRightRound.gif"/>

<asp:Image runat="server" SkinID="RoundedEdgeBottom" src="/images/Saler/ActivityFooteround.gif"/>

Login.aspx file @Page declaration:

<%@ Page Language="C#" MasterPageFile="~/Masters/Entrance.master" CompileWith="Login.aspx.cs" ClassName="Login_aspx" Title="Saler Login Page" Theme="Basic" %>

Masters/Entrance.master file:

<%@ Master Language="C#" CompileWith="Entrance.master.cs" ClassName="Entrance_master" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="https://www.w3.org/1999/xhtml" >
<head runat="server">
<link rel="STYLESHEET" type="text/css" href="/Styles/Saler/Basic.css" />
<title>Entrance Master Page</title>
</head>
<body>
<form runat="server">
<input type="hidden" id="__EVENTTARGET" name="__EVENTTARGET"> <input id="__EVENTARGUMENT" type="hidden" name="__EVENTARGUMENT">
<table cellSpacing="0" cellPadding="0" width="100%" border="0">
<tr>
<td>
<table cellSpacing="0" cellPadding="0" width="100%" border="0">
<tr>
<td width="24%"><asp:Image Height="59" Runat="server" SkinID="Logo" width="100%" /></td>
<td vAlign="top" align="right" width="76%" class="ColouredBackground"><asp:Image Runat="Server" Height="28" Width="28" SkinID="RoundedEdgeTop" /></td>
</tr>
<asp:ContentPlaceHolder ID="UserIdentificationPlaceholder" runat="Server"></asp:ContentPlaceHolder>
</table>
<table>
<tr>
<td width="100%">
<asp:contentplaceholder id="EntranceContentPlaceholder" runat="server">
</asp:contentplaceholder>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="height: 44px">
<table cellSpacing="0" cellPadding="0" width="100%" border="0">
<tr background="/images/Saler/ActivityFooterLineBak.gif">
<td background="/images/Saler/ActivityFooterLineBak.gif"><IMG height="6" src="/images/Saler/ActivityFooterLeftLine.gif" width="38"></td>
<td align="right" background="/images/Saler/ActivityFooterLineBak.gif"><IMG height="6" src="/images/Saler/ActivityFooterRightLine.gif" width="28"></td>
</tr>
<tr vAlign="top" align="right" class="ColouredBackground">
<td colSpan="2"><asp:Image Runat="server" Height="19" Width="28" SkinID="RoundedEdgeBottom" /></td>
</tr>
</table>
</td>
</tr>
</table>

</form>
&nbsp;
</body>
</html>
<%@ Page Language="C#" MasterPageFile="~/Masters/Entrance.master" CompileWith="Login.aspx.cs" ClassName="Login_aspx" Title="Saler Login Page" %><%@ Page Language="C#" MasterPageFile="~/Masters/Entrance.master" CompileWith="Login.aspx.cs" ClassName="Login_aspx" Title="Saler Login Page" %><%@ Page Language="C#" MasterPageFile="~/Masters/Entrance.master" CompileWith="Login.aspx.cs" ClassName="Login_aspx" Title="Saler Login Page" %>

Note that, unfortunately, one cannot set the theme of a page at the master page level. It has to be done at the page level. I'm hoping that gets fixed in subsequent releases of ASP.NET 2.0.