Click here to Skip to main content
Email Password   helpLost your password?

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 web site, and is made persistent through the use of a cookie.

Try the online demo

Using the control

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

  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 the 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>

Warning: 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 the 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:

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 2 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:
    <%@ 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:

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

History

Version 1.0.0 Version 1.0.1:

Points of interest

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralPls send me C# code of this control
RAKESH gaur mkcl
0:40 16 Oct '08  
please can you send it to me ??pls sir I have very urgency .plss
mkclrakesh@gmail.com
thanks a lot
GeneralException with AJAX postback?
jwr4
10:15 12 Aug '08  
The following information was included with the event:

3005
An unhandled exception has occurred.
8/12/2008 10:59:31 AM
8/12/2008 2:59:31 PM
5d5e1866d2f2400c864234ed42a5309d
377
2
0
4ac704d-9-128630262097594890
Full
/AdvanceWeb1.1
P:\Custom\CB\Advance\Advance1.1\AdvanceWeb1.1\
JWR4
8736
WebDev.WebServer.EXE
WILTON\jwr4
NullReferenceException
Object reference not set to an instance of an object.
http://localhost:57103/AdvanceWeb1.1/default.aspx
/AdvanceWeb1.1/default.aspx
127.0.0.1
WILTON\jwr4
True
NTLM
WILTON\jwr4
8
WILTON\jwr4
False
at rw.ThemeSwitcherModule.PreRequestHandlerExecute(Object sender, EventArgs e)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Theme switcher works AOK on non-ajax pages.
GeneralRe: Exception with AJAX postback?
jwr4
15:18 12 Aug '08  
I added this to themeswitchermodule.vb:

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

'added to avoid AJAX Issues
If (Not CurrentContext.Request.Headers("x-microsoftajax") Is Nothing) Then Return


So the handler does nothing if it is an AJAX request. Problem solved.
GeneralUse ThemeSwitcher in Updatepanel Ajax
ab_dc
10:45 21 Mar '08  
Hello this is useful control , but what about using ajax ?? I try to put it inside UpdatePanel but , error ,I added it as " AsyncPostBackTrigger " no error , but nothing ?? I try to add it as " PostBackTrigger " it makes Postback , so any ideas, thank you again for your great control
GeneralAnother method of transfering the theme from one page to another
vlad.ardelean
1:36 19 Mar '08  
First of all, great control.
Is there any other method of storing the selected theme except for cookies and ViewState?
Because on the application I'm working I am not allowed to use cookies and the ViewState is disabled.
GeneralRe: Another method of transfering the theme from one page to another
Jos Branders
5:39 22 Mar '08  
A database?

Jos
GeneralRe: Another method of transfering the theme from one page to another
vlad.ardelean
5:46 22 Mar '08  
Yes. Well, that's what I thought. I'm doing it right now.
Thanks Jos
GeneralTheme disappears when making an ajax postback??
Morten Neesgaard
8:42 16 Jun '07  
When I make an ajax postback the themeswitcher forgots which theme was selected and doesn't select the default theme either. Please help.
GeneralRe: Theme disappears when making an ajax postback??
Morten Neesgaard
14:57 16 Jun '07  
Solved... The app them folder contained other letters than a-z.
GeneralNice!!
KoaQiu
1:06 11 Apr '07  
非常感谢!
GeneralRe: Nice!!
alegozalves
10:37 25 Mar '08  
Totally agree!
a very nice and useful control...
thanks! Big Grin
GeneralRe: Nice!!
Member 2970270
7:42 1 Aug '08  
I agree--very handy control, thank you Jos! Big Grin
GeneralThe module was expected to contain an assembly manifest.
Netrooo
15:05 18 Mar '07  
I've added the DLL to my Bin folder and registered the assembly in top of my masterpage. I've also included the lines in the web.config file but I keep receiving the following error:

Error 104 Could not load file or assembly 'themeSwitcher' or one of its dependencies. The module was expected to contain an assembly manifest.

My project is written in C#. What should I do? Thanks.
GeneralHidden folder in App_Theme folder [modified]
Jorg#10
22:44 9 Oct '06  
Hi,
I tried your control and it's beautiful.
But I have a CVS source controlled project so in each subfolder there is a CVS hidden folder.
So your control show me the existence of a CVS theme.

I have modified ThemeSwitcher.vb to exclude hidden folders from available themes:

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
...

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)
If (Not ((dirInfo.Attributes And FileAttributes.Hidden) = FileAttributes.Hidden)) Then Items.Add(dirInfo.Name)
End If Next End If
...
End Sub


-- modified at 16:10 Friday 13th October, 2006
Generaldownload is version 1.0.0.0
daz13
17:07 2 Oct '06  
Hi, and thanks for the code.

I noticed the download code is of version 1.0.0.0 - not the updated version containing the default theme. Could the newest version be made available?
AnswerRe: download is version 1.0.0.0
Jos Branders
2:15 9 Oct '06  
Thanks for letting me know, Daz!

I've updated the source, it should be 1.0.1.0 now.

Jos
GeneralRe: download is version 1.0.0.0
daz13
19:57 9 Oct '06  
Great! thanks again for the code. It's now working exactly as I hoped.

Daz.
GeneralBroken link
bailes
17:28 3 Jul '06  
The link to the new download seems to be broken.

Thank you for sharing this with us.

Don Bailes
Computer and Information Sciences
East Tennessee State University
Johnson City, TN 37614
GeneralJust wanted to say!
HowerS
14:08 9 May '06  
This wa absolutely perfect... Thanks!
GeneralC# same control
WaleedS
4:42 8 May '06  
Hello
I wanted to develop the same control using C#, but I found yours, which is very good, so I decided to convert your VB to C#.
I created a separate project (User Control) and I successfully translate the VB to C#, then I added the same HTTP tag in the web.config, but when I run the application, I got error at the HTPP line says, can't find control "SkinPicker" I only change the name of the control and the namespace, what else do I miss here Confused ...


Thanks, Best Regards
Waleed Seada
AnswerRe: C# same control
Jos Branders
4:56 9 May '06  
Did your C# code compile and did you put the assembly in the bin folder?

Just guessing here...

Jos
GeneralRe: C# same control
WaleedS
3:01 10 May '06  
Thanks a lotBig Grin , I did manage to get it to work ...



Thanks, Best Regards
Waleed Seada
GeneralRe: C# same control
scottbunnett
17:49 9 Dec '06  
could you please post the code?
GeneralRe: C# same control
Member 2970270
7:45 1 Aug '08  
Ditto on that. A C# version would be nice. My project is (mostly) C# too. The VB version works fine, but for consistency's sake it would helpful to have the C# version...
GeneralRe: C# same control
ab_dc
2:30 22 Mar '08  
please can you post the c# code or send it to me ??
mahmoud.ramzy@hotmail.com
thanks a lot


Last Updated 11 Nov 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010