Click here to Skip to main content
Click here to Skip to main content

Theme Switcher Control

By , 11 Nov 2006
Rate this:
Please Sign up or sign in to vote.

Sample Image - themeswitcher.gif

Introduction

This free ThemeSwitcher control allows the user to choose one of the available themes (ASP.NET 2.0). The theme is applied automatically to all ASP.NET pages in the website, and is made persistent through the use of a cookie.

Using the control

You need to do three things to use this control in your website:

  1. Add multiple themes to your project
  2. Add the HTTP Module handler to web.config
  3. Create a page for the user to select a theme, and add the theme switcher control to this page

Add multiple themes

Add multiple themes to your application in the usual way. In Visual Studio 2005, you can add a new theme by right clicking on the root of the application, selecting "Add ASP.NET Folder", followed by "Theme". In the theme folder, you can add style sheet files (.css), skin files (.skin), images, etc. Repeat the same procedure for each additional theme.

If you want to provide a default theme, just create a new theme folder with the name "Default". If a folder with that name exists, it will be used as the default theme by the HTTP Module handler until the user selects another theme with the theme switcher. If you don't provide a default theme, the user will get no themes on his pages until he selects a particular theme.

Add the HTTP Module handler

In web.config, you need to add this code to the <system.web> element:

<httpModules>
    <add type="rw.ThemeSwitcherModule, ThemeSwitcher" 
         name="ThemeSwitcherHttpModule" />
</httpModules>

This setting causes a server error in every page having a <head> tag without the runat="server" attribute! Make sure this attribute is set in every ASPX page of your site. By default, Visual Studio 2005 and Visual Web Developer add this attribute to every page, but you may still have pages that were created for ASP.NET 1.x, when this attribute was not needed.

Create a page for switching themes

Typically, you could create a single page for the user to select a theme. You need to add the control to this page only. As soon as the user selects a theme from the list, this theme will be added to all the pages in the entire site.

As an alternative, you could add a theme switcher to the master page, making the theme selection available on every page in the site.

Before using the control in a page, you can install it in the standard way:

  • create a "bin" folder inside the application root of your website (if it's not already there)
  • copy the assembly file themeswitcher.dll into the bin folder

You may want to add the control to the toolbox of your editor. This will allow you to set its properties in the Property Pane. Follow the editor's procedure to add a control to the toolbox.

There are two ways to add the control to your page or master page:

  1. Drag the control from the toolbox onto the page (if it was installed on the toolbox).
  2. Add the code manually. Add this line to the top of your page:
  3. <%@ Register TagPrefix="rw" Namespace="rw" Assembly="ThemeSwitcher" %>

    Then, add a tag like this where you want the theme list to be displayed:

    <rw:ThemeSwitcher id="ThemeSwitcher1" runat="server" >/>

You can check the demo file demo.aspx for a sample.

Finally, you can set two properties:

  • Set the AllowNoTheme property to "true" if you want to allow the user to choose no theme at all
  • Set the NoThemeText property if you don't want to use the default text "none"

How it works

The code is composed of two parts, one for the theme list control, and one for the HTTP module handling the theme selection.

Theme list code

This is a control derived from the ListBox control. In the Page_Load event, the control will enumerate all the subfolders of the App_Themes folder of the site. The names of these subfolders are also the names of the available themes. This is the code for the OnLoad handler:

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    MyBase.OnLoad(e)
    Me.ID = "lbThemeSwitcher" ' force an ID, so we can use it in HttpModule
    If (Not Page.IsPostBack) Then
        ' AutoPostBack will be handled in HttpModule
        Me.AutoPostBack = True
        If (Me.AllowNoTheme) Then
            ' First item is "none"
            Items.Add(New ListItem(NoThemeText, "0"))
        End If
        If (Directory.Exists(Page.MapPath("~/App_Themes"))) Then
            ' Enumerate the subfolders of the themes folder 
            ' and add them to the list
            Dim subdirs() As String = _
                Directory.GetDirectories(Page.MapPath("~/App_Themes"))
            For Each dir As String In subdirs
                Dim dirInfo As New DirectoryInfo(dir)
                Items.Add(dirInfo.Name)
            Next
        End If
    End If
    ' set selection to current value of the theme
    SelectedIndex = -1
    If (Page.Theme Is Nothing OrElse Page.Theme = "") Then
        SelectedIndex = 0
    Else
        Dim li As ListItem = Items.FindByValue(Page.Theme)
        If (li IsNot Nothing) Then li.Selected = True
    End If
End Sub

HTTP Module code

This is a class implementing the IHttpModule interface. It will intercept every page request and automatically apply the selected theme. This will be done in the PreRequestHandler:

Protected Sub PreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs)
    Dim CurrentContext As HttpContext = HttpContext.Current
    If (Not TypeOf CurrentContext.Handler Is Page) Then Return
    Dim myPage As Page = CurrentContext.Handler
    If Not myPage Is Nothing Then

        ' This 8 lines below handle master pages. Courtesy of Craig G Fraser
        Dim sUniqueID As String = "lbThemeSwitcher"
        Dim sCtrlID As String
        For Each sCtrlID In CurrentContext.Request.Form.AllKeys
            If sCtrlID.Contains("lbThemeSwitcher") Then
                sUniqueID = sCtrlID
                Exit For
            End If
        Next

        Dim theme As Object = CurrentContext.Request.Form(sUniqueID)
        If (Not theme Is Nothing) Then
            ' this is postback from the page with the theme switcher list
            ' handle the user selection in the theme list
            If (theme.ToString() = "0") Then
                ' user chose "none"
                myPage.Theme = ""
                ' delete the cookie
                CurrentContext.Response.Cookies(CookieName()).Expires = _
                                               DateTime.Today.AddDays(-1)
                Return
            End If
            If (ThemeExists(theme)) Then myPage.Theme = theme
            ' set a cookie for persistence
            CurrentContext.Response.Cookies(CookieName()).Value = theme
            CurrentContext.Response.Cookies(CookieName()).Expires = _
                             DateTime.Today.AddDays(90) ' 90 days
        Else
            ' for other pages with no theme switcher on them
            Dim cookie As Object = _
                CurrentContext.Request.Cookies(CookieName())
            If (Not cookie Is Nothing AndAlso cookie.Value <> "") Then
                ' if there's a cookie, get the theme from the cookie
                If (ThemeExists(cookie.Value)) Then myPage.Theme = cookie.Value
                cookie.Expires = DateTime.Today.AddDays(90) ' reset expiration date 
            Else
                ' if there's no cookie, select the default theme (if it exists)
                ' the developer should provide a theme with the name "Default"
                ' if this behavior is wanted
                If (ThemeExists("Default")) Then myPage.Theme = "Default"
                Dim DefaultThemeName As String = _
                    System.Configuration.ConfigurationManager.AppSettings("DefaultThemeName")
                If (DefaultThemeName <> "" And _
                    ThemeExists(DefaultThemeName)) Then myPage.Theme = DefaultThemeName
            End If
        End If
    End If
End Sub

Known issues

  • When Server.Transfer is used, the target page may appear with no theme at all.

History

Version 1.0.0

  • First official version.

Version 1.0.1

  • Added the AllowNoTheme property.
  • Added support for a default theme. When a theme with the name "Default" exists, it will be used by default.
  • Inherited properties from ListBox that are not useful are now hidden.

Points of interest

  • Using IHttpModule
  • ASP.NET 2.0 themes

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jos Branders
Web Developer
Belgium Belgium
No Biography provided

Comments and Discussions

 
GeneralPls send me C# code of this control PinmemberRAKESH gaur mkcl15-Oct-08 23:40 
QuestionException with AJAX postback? Pinmemberjwr412-Aug-08 9:15 
AnswerRe: Exception with AJAX postback? Pinmemberjwr412-Aug-08 14:18 
GeneralUse ThemeSwitcher in Updatepanel Ajax Pinmemberab_dc21-Mar-08 9:45 
GeneralAnother method of transfering the theme from one page to another Pinmembervlad.ardelean19-Mar-08 0:36 
GeneralRe: Another method of transfering the theme from one page to another PinmemberJos Branders22-Mar-08 4:39 
GeneralRe: Another method of transfering the theme from one page to another Pinmembervlad.ardelean22-Mar-08 4:46 
QuestionTheme disappears when making an ajax postback?? PinmemberMorten Neesgaard16-Jun-07 7:42 
AnswerRe: Theme disappears when making an ajax postback?? PinmemberMorten Neesgaard16-Jun-07 13:57 
GeneralNice!! PinmemberKoaQiu11-Apr-07 0:06 
GeneralRe: Nice!! Pinmemberalegozalves25-Mar-08 9:37 
GeneralRe: Nice!! PinmemberMember 29702701-Aug-08 6:42 
GeneralThe module was expected to contain an assembly manifest. PinmemberNetrooo18-Mar-07 14:05 
GeneralHidden folder in App_Theme folder [modified] PinmemberJorg#109-Oct-06 21:44 
Generaldownload is version 1.0.0.0 Pinmemberdaz132-Oct-06 16:07 
AnswerRe: download is version 1.0.0.0 PinmemberJos Branders9-Oct-06 1:15 
GeneralRe: download is version 1.0.0.0 Pinmemberdaz139-Oct-06 18:57 
GeneralBroken link Pinmemberbailes3-Jul-06 16:28 
GeneralJust wanted to say! PinmemberHowerS9-May-06 13:08 
GeneralC# same control PinmemberWaleedS8-May-06 3:42 
AnswerRe: C# same control PinmemberJos Branders9-May-06 3:56 
GeneralRe: C# same control PinmemberWaleedS10-May-06 2:01 
GeneralRe: C# same control Pinmemberscottbunnett9-Dec-06 16:49 
GeneralRe: C# same control PinmemberMember 29702701-Aug-08 6:45 
GeneralRe: C# same control Pinmemberab_dc22-Mar-08 1:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 11 Nov 2006
Article Copyright 2006 by Jos Branders
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid