Chapter 6. Designing Websites with Themes

<feature>

IN THIS CHAPTER

</feature>

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 standards-compliant 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_ThemesSimple folder), then you can modify the appearance of all TextBox controls in all pages that use the Simple Theme.

Example 6.1. SimpleTextBox.skin

<asp:TextBox
    BackColor="Yellow"
    BorderStyle="Dotted"
    Runat="Server" />

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.

Example 6.2. ShowSkin.aspx

<%@ Page Language="C#" Theme="Simple" %>
<!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>Show Skin</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:TextBox
        Runat="server" />

    </div>
    </form>
</body>
</html>

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).

Using a TextBox Skin.

Figure 6.1. Using a TextBox Skin.

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.

Note

By default, all control properties are themeable (can be modified in a Skin file). However, certain control properties are decorated with the Themeable(False) attribute, which disables theming.

Creating Named Skins

In the previous section, we created something called a Default Skin. A Default Skin is applied to every instance of a control of a certain type. For example, a Default Skin is applied to every instance of a TextBox control.

You also have the option of creating a Named Skin. When you create a Named Skin, you can decide when you want to apply the Skin. For example, you might want required fields in a form to appear with a red border. In that case, you can create a Named Skin and apply the Skin to only particular TextBox controls.

The Skin in Listing 6.3 contains both a Default Skin and a Named Skin for a TextBox control.

Example 6.3. Simple2TextBox.skin

<asp:TextBox
    SkinID="DashedTextBox"
    BorderStyle="Dashed"
    BorderWidth="5px"
    Runat="Server" />

<asp:TextBox
    BorderStyle="Double"
    BorderWidth="5px"
    Runat="Server" />

The first TextBox in Listing 6.3 is an example of a Named Skin. Notice that it includes a SkinID property. The SkinID property represents the name of the Named Skin. You use the value of this property when applying the Skin in a page.

The file in Listing 6.3 also includes a Default Skin for a TextBox control. The Default Skin does not include a SkinID property. If a TextBox control in a page is not associated with a Named Skin, then the Default Skin is applied to the TextBox.

A Theme can contain only one Default Skin for each type of control. However, a Theme can contain as many Named Skins as you please. Each Named Skin must have a unique name.

The page in Listing 6.4 contains two TextBox controls. The first TextBox control includes a SkinID attribute. This attribute causes the Named Skin to be applied to the control. The second TextBox, on the other hand, does not include a SkinID property. The Default Skin is applied to the second TextBox control.

Example 6.4. ShowNamedSkin.aspx

<%@ Page Language="C#" Theme="Simple2" %>
<!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>Show Named Skin</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:TextBox
        id="txtFirstName"
        SkinID="DashedTextBox"
        Runat="server" />

    <br /><br />

    <asp:TextBox
        id="txtLastName"
        Runat="server" />

    </div>
    </form>
</body>
</html>

When you open the page in Listing 6.4, the first TextBox appears with a dashed border and the second TextBox appears with a double border (see Figure 6.2).

Using Named Skins.

Figure 6.2. Using Named Skins.

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.

Example 6.5. Simple3Label.skin

<asp:Label
    BackColor="Orange"
    Runat="Server" />

The Skin in Listing 6.5 sets the background color of all Label controls to the color Orange.

Now, image that you apply the Skin in Listing 6.5 to the ASP.NET page in Listing 6.6.

Example 6.6. ShowSkinTheme.aspx

<%@ Page Language="C#" Theme="Simple3" %>
<!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>Show Skin Theme</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:Label
        id="Label1"
        Text="What color background do I have?"
        BackColor="red"
        Runat="server" />

    </div>
    </form>
</body>
</html>

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.

Example 6.7. ShowSkinStyleSheetTheme.aspx

<%@ Page Language="C#" StyleSheetTheme="Simple3" %>
<!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 id="Head1" runat="server">
    <title>Show Skin Style Sheet Theme</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:Label
        id="Label1"
        Text="What color background do I have?"
        BackColor="red"
        Runat="server" />

    </div>
    </form>
</body>
</html>

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.

Disabling Themes

Every ASP.NET control includes an EnableTheming property. You can use the EnableTheming property to prevent a Skin from being applied to a particular control in a page.

For example, the page in Listing 6.8 contains two Calendar controls. The second Calendar control has its EnableTheming property set to the value False (see Figure 6.3).

Disabling a Theme.

Figure 6.3. Disabling a Theme.

Example 6.8. ShowEnableTheming.aspx

<%@ Page Language="C#" Theme="Simple4" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Show EnableTheming</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:Calendar
        id="Calendar1"
        Runat="server" />

    <br /><br />

    <asp:Calendar
        id="Calendar2"
        EnableTheming="false"
        Runat="server" />

    </div>
    </form>
</body>
</html>

The page in Listing 6.8 includes a Theme attribute that applies the Simple Theme to the page. The Simple Theme includes the Skin in Listing 6.9.

Example 6.9. Simple4Calendar.skin

<asp:Calendar
    BackColor="White"
    BorderColor="White"
    BorderWidth="1px"
    Font-Names="Verdana"
    Font-Size="9pt"
    ForeColor="Black"
    NextPrevFormat="FullMonth"
    Width="400px"
    Runat="Server">
    <SelectedDayStyle
        BackColor="#333399"
        ForeColor="White" />
    <OtherMonthDayStyle
        ForeColor="#999999" />
    <TodayDayStyle
        BackColor="#CCCCCC" />
    <NextPrevStyle
        Font-Bold="True"
        Font-Size="8pt"
        ForeColor="#333333"
        VerticalAlign="Bottom" />
    <DayHeaderStyle
        Font-Bold="True"
        Font-Size="8pt" />
    <TitleStyle
        BackColor="White"
        BorderColor="Black"
        BorderWidth="4px"
        Font-Bold="True"
        Font-Size="12pt"
        ForeColor="#333399" />
</asp:Calendar>

When you open the page in Listing 6.9 in a web browser, the Skin is applied to the first Calendar control but not the second Calendar control.

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.

Example 6.10. Web.Config

<configuration>
<system.web>

  <pages theme="Site" />

</system.web>
</configuration>

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.

Example 6.11. Web.Config

<configuration>
<system.web>

  <pages styleSheetTheme="Site" />

</system.web>
</configuration>

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.

Example 6.12. DisablePageTheme.aspx

<%@ Page Language="C#" EnableTheming="false" %>
<!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>Disable Page Theme</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:Label
        id="Label1"
        Text="Don't Theme Me!"
        Runat="server" />

    </div>
    </form>
</body>
</html>

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.

Example 6.13. App_ThemesStyleThemeSimpleStyle.css

html
{
    background-color:gray;
    font:14px Georgia,Serif;
}

.content
{
    margin:auto;
    width:600px;
    border:solid 1px black;
    background-color:White;
    padding:10px;
}

h1
{
    color:Gray;
    font-size:18px;
    border-bottom:solid 1px orange;
}

label
{
    font-weight:bold;
}

input
{
    background-color:Yellow;
    border:double 3px orange;
}

.button
{
    background-color:#eeeeee;
}

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.

Example 6.14. ShowSimpleCSS.aspx

<%@ Page Language="C#" Theme="StyleTheme" %>
<!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 id="Head1" runat="server">
    <title>Show Simple CSS</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="content">

    <h1>Registration Form</h1>

    <asp:Label
        id="lblFirstName"
        Text="First Name:"
        AssociatedControlID="txtFirstName"
        Runat="server" />
    <br />
    <asp:TextBox
        id="txtFirstName"
        Runat="server" />

    <br /><br />

    <asp:Label
        id="lblLastName"
        Text="Last Name:"
        AssociatedControlID="txtLastName"
        Runat="server" />
    <br />
    <asp:TextBox
        id="txtLastName"
        Runat="server" />

    <br /><br />

    <asp:Button
        id="btnSubmit"
        Text="Submit Form"
        CssClass="button"
        Runat="server" />

    </div>
    </form>
</body>
</html>

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.

Styling with Cascading Style Sheets.

Figure 6.4. Styling with Cascading Style Sheets.

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.

Note

In this book, you will notice that I try to avoid formatting controls by using control properties. Instead, I perform all the formatting in a Style Sheet embedded in the page (using the <style> tag). I would prefer to place all the control formatting in an external Style Sheet, but that would require creating a separate file for each code sample, which would make this book much longer than it already threatens to be.

Adding Multiple Cascading Style Sheets to a Theme

You can add as many Cascading Style Sheet files to a Theme folder as you need. When you add multiple Cascading Style Sheets to a Theme, all the Cascading Style Sheets are applied to a page when the Theme is applied to a page.

The order in which an external Style Sheet is linked to a page can be important. For example, style sheet rules in one Style Sheet can override style sheet rules in another Style Sheet.

When you add multiple Style Sheets to a Theme, the style sheets are linked to a page in alphabetical order (in the order of the Style Sheet file name). For example, if the Theme contains three Style Sheet files named ThemeA.css, ThemeB.css, and ThemeC.css, then the following three links are added to a page:

<link href="App_Themes/Simple/ThemeA.css" type="text/css" rel="stylesheet" />
<link href="App_Themes/Simple/ThemeB.css" type="text/css" rel="stylesheet" />
<link href="App_Themes/Simple/ThemeC.css" type="text/css" rel="stylesheet" />

If you want to control the order in which Style Sheets are applied to a page, then you need to follow a naming convention.

Changing Page Layouts with Cascading Style Sheets

Because you can use a Cascading Style Sheet to change the layout of a page, you can use a Theme to control page layout.

For example, the page in Listing 6.15 contains three <div> tags. By default, if you open the page, the contents of the <div> tags are stacked one on top of another (see Figure 6.5).

Page without Cascading Style Sheet.

Figure 6.5. Page without Cascading Style Sheet.

Example 6.15. ShowLayout.aspx

<%@ Page Language="C#" %>
<!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>Show Layout</title>
</head>
<body>
    <form id="form1" runat="server">

    <div id="div1">
        First div content
        <br />First div content
        <br />First div content
        <br />First div content
        <br />First div content
    </div>

    <div id="div2">
        Second div content
        <br />Second div content
        <br />Second div content
        <br />Second div content
        <br />Second div content
    </div>

    <div id="div3">
        Third div content
        <br />Third div content
        <br />Third div content
        <br />Third div content
        <br />Third div content
    </div>

    </form>
</body>
</html>

If you add the Cascading Style Sheet in Listing 6.16, you can modify the layout of the <div> tags (see Figure 6.6). The Style Sheet in Listing 6.16 displays the <div> tags in three columns. (The Stylesheet floats each of the <div> tags.)

Using a floating layout.

Figure 6.6. Using a floating layout.

Example 6.16. Float.css

html
{
    background-color:Silver;
    font:14px Arial,Sans-Serif;
}

#div1
{
    float:left;
    width:25%;
    margin:15px;
    padding:10px;
    background-color:White;
}

#div2
{
    float:left;
    width:25%;
    margin:15px;
    padding:10px;
    background-color:White;
}

#div3
{
    float:left;
    width:25%;
    margin:15px;
    padding:10px;
    background-color:White;
}

Alternatively, you can position the <div> tags absolutely by using the left and top style properties. The Style Sheet in Listing 6.17 reverses the order in which the three <div> tags are displayed (see Figure 6.7).

Using an absolute layout.

Figure 6.7. Using an absolute layout.

Note

The Cascading Style Sheets in this section work equally well with Internet Explorer 6, Firefox 1, and Opera 8.

Example 6.17. Absolute.css

html
{
    background-color:Silver;
    font:14px Arial,Sans-Serif;
}

#div3
{
    position:absolute;
    left:15px;
    top:15px;
    width:200px;
    padding:10px;
    background-color:White;
}

#div2
{
    position:absolute;
    left:250px;
    top:65px;
    width:200px;
    padding:10px;
    background-color:White;
}

#div1
{
    position:absolute;
    left:485px;
    top:115px;
    width:200px;
    padding:10px;
    background-color:White;
}

The point of this section is to demonstrate that Cascading Style Sheets are very powerful. You can create elaborate website designs simply by creating the right Style Sheet. If you want to see some samples of some amazing website designs performed with Cascading Style Sheets, visit the CSS Zen Garden located at http://www.CSSZenGarden.com.

Creating Global Themes

You can share the same Theme among multiple web applications running on the same web server. A Global Theme can contain both Skin files and Cascading Style Sheet files. Creating a Global Theme is useful when you want to create one company-wide website design and apply it to all your company’s applications.

You create a Global Theme by adding the Theme to the Themes folder located at the following path:

WINDOWSMicrosoft.NETFrameworkv2.0.50727ASP.NETClientFilesThemes

After you add a Theme folder to this path, you can immediately start using the Theme in any file system-based website.

If you want to use the Theme in an HTTP-based website, you need to perform an additional step. You must add the Theme folder to the following path:

Inetpubwwwrootaspnet_clientsystem_webv2.0.50727Themes

You can copy the Theme to this folder manually or you can use the aspnet_regiis tool to copy the Theme folder. Execute the aspnet_regiis tool from the command line like this:

aspnet_regiis -c

The aspnet_regiis tool is located in the WindowsMicrosoft.NETFrameworkv2.0.50727 folder. You can open a command prompt and navigate to this folder to execute the tool. Alternatively, if you have installed the Microsoft .NET Framework SDK, then you can execute the tool by opening the SDK Command Prompt from the Microsoft .NET Framework SDK program group.

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).

Selecting a Theme programmatically.

Figure 6.8. Selecting a Theme programmatically.

Example 6.18. DynamicTheme.aspx

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">

    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Request["theme"] != null)
        {
            switch (Request["theme"])
            {
                case "Green":
                    Profile.userTheme = "GreenTheme";
                    break;
                case "Pink":
                    Profile.userTheme = "PinkTheme";
                    break;
            }
        }
        Theme = Profile.userTheme;
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Dynamic Theme</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="content">

    <h1>Dynamic Theme</h1>

    Please select a Theme:
    <ul>
    <li>
        <a href="DynamicTheme.aspx?theme=Green">Green Theme</a>
    </li>
    <li>
        <a href="DynamicTheme.aspx?theme=Pink">Pink Theme</a>
    </li>
    </ul>

    </div>
    </form>
</body>
</html>

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.

Example 6.19. Web.Config

<configuration>
  <system.web>
    <profile>
      <properties>
        <add name="UserTheme" />
      </properties>
    </profile>
  </system.web>
</configuration>

Because the control tree has not been created when the PreInit event is raised, you can’t refer to any controls in a page. Notice that hyperlinks are used in Listing 6.18 to select a Theme. You could not use a DropDownList control because the DropDownList control would not have been created.

Note

If you need to load a Theme dynamically for multiple pages in an application, then you can override the OnPreInit() method of the base Page class. This technique is discussed in the “Loading Master Pages Dynamically for Multiple Content Pages” section of Chapter 5.

Applying Skins Dynamically

You can apply skins dynamically to particular controls in a page. In the Page PreInit event, you can modify a control’s SkinID property programmatically.

For example, the page in Listing 6.20 enables a user to select a favorite skin for a GridView control. The GridView control displays a list of movies (see Figure 6.9).

Example 6.20. ShowDynamicSkin.aspx

<%@ Page Language="C#" Theme="DynamicSkin" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">

    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Request["skin"] != null)
        {
            switch (Request["skin"])
            {
                case "professional":
                    grdMovies.SkinID = "Professional";
                    break;
                case "colorful":
                    grdMovies.SkinID = "Colorful";
                    break;
            }
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Show Dynamic Skin</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:GridView
        id="grdMovies"
        DataSourceID="srcMovies"
        Runat="server" />

    <asp:SqlDataSource
        id="srcMovies"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Id,Title,Director FROM Movies"
        Runat="server" />

    <hr />

    <a href="showdynamicskin.aspx?skin=professional">Professional</a>
    &nbsp;|&nbsp;
    <a href="showdynamicskin.aspx?skin=colorful">Colorful</a>

    </div>
    </form>
</body>
</html>
Applying a Skin programmatically.

Figure 6.9. Applying a Skin programmatically.

A hyperlink is used to select a particular Skin. The Skin is applied to the GridView in the PreInit event when a particular value is assigned to the GridView control’s SkinID property.

Of course, I don’t recommend doing this. It makes more sense to use a Cascading Style Sheet and modify a control’s CssClass property. This alternate approach is demonstrated by the page in Listing 6.21.

Example 6.21. ShowDynamicCSS.aspx

<%@ Page Language="C#" Theme="DynamicSkin" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        grdMovies.CssClass = ddlCssClass.SelectedItem.Text;
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Show Dynamic CSS</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:GridView
        id="grdMovies"
        DataSourceID="srcMovies"
        HeaderStyle-CssClass="Header"
        AlternatingRowStyle-CssClass="Alternating"
        GridLines="none"
        Runat="server" />

    <asp:SqlDataSource
       id="srcMovies"
       ConnectionString="<%$ ConnectionStrings:Movies %>"
       SelectCommand="SELECT Id,Title,Director FROM Movies"
       Runat="server" />

    <hr />

    <asp:Label
        id="lblCssClass"
        Text="Select Style:"
        AssociatedControlID="ddlCssClass"
        Runat="server" />
    <asp:DropDownList
        id="ddlCssClass"
        Runat="server">
        <asp:ListItem Text="Professional" />
        <asp:ListItem Text="Colorful" />
    </asp:DropDownList>
    <asp:Button
        id="btnSubmit"
        Text="Select"
        Runat="server" OnClick="btnSubmit_Click" />

    </div>
    </form>
</body>
</html>

Note that in this code sample, unlike the previous one, you can use a DropDownList and Button control to change the appearance of the GridView control when modifying the CssClass property. Because you can modify the CssClass property during any event before the page is rendered, you can handle the Button Click event to modify the value of the CssClass property.???

Modifying a CssClass programmatically.

Figure 6.10. Modifying a CssClass programmatically.

Summary

In this chapter, you learned how to create a consistent look for your website by taking advantage of ASP.NET Themes. In the first section, you learned how to modify the appearance of controls in a page with Skins. You learned how to create both Default and Named Skins. You also learned how to apply a Theme by using the Theme attribute and StyleSheetTheme attribute.

Next, you learned how to add Cascading Style Sheets to Themes. I recommended that you take advantage of Cascading Style Sheets and avoid Skins whenever possible.

We also discussed how you can create Global Themes. You learned how to create a Theme that you can apply to every application executing on a web server.

Finally, you learned how to dynamically apply Themes. You learned how to use the PreInit event to dynamically apply either an entire Theme or a particular Skin at runtime.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.17.40