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

Sample Image - dynamicThemes.jpg

Introduction

ASP.NET 2.0 makes dynamic themes really easy. No need to envy someone having cool multiple themes, you can have your own instantly! This article gives you step by step instructions on how to make dynamic themes in C#. You can try this code out with the Personal Web Site Starter Kit.

The result

Live demo is available here. Click on "change themes" on the top left corner, under the logo.

The code

  1. Step 1: Under the App_Code folder, we add a class file named Theme.cs:
  2. public class Theme
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public Theme(string name)
        {
            Name = name;
        }
    }
  3. Step 2: Under the App_Code folder, we add a ThemeManager class file named ThemeManager.cs. This will list all the available themes under the /App_Themes folder.
  4. using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    public class ThemeManager
    {
    #region Theme-Related Method
        public static List<Theme> GetThemes()
        {
            DirectoryInfo dInfo = new DirectoryInfo(
              System.Web.HttpContext.Current.Server.MapPath("App_Themes"));
            DirectoryInfo[] dArrInfo = dInfo.GetDirectories();
            List<Theme> list = new List<Theme>();
            foreach (DirectoryInfo sDirectory in dArrInfo)
            {
                Theme temp = new Theme(sDirectory.Name);
                list.Add(temp);
            }
            return list;
        }
    #endregion
    }
  5. Step 3: Comment out any pre-defined themes such as <!--<pages styleSheetTheme="Black"/>--> in the web.config. You don't need this because the application level default theme will be specified in the BasePage class in Step 6.
  6. Step 4: In you master page, such as Default.master, add a data source and a radiobutton list. You can use a dropdownlist if you would prefer that.
  7. <asp:ObjectDataSource ID="ThemeDataSource" runat="server" 
     SelectMethod="GetThemes" TypeName="ThemeManager" ></asp:ObjectDataSource>
    <asp:RadioButtonList ID="strTheme" runat="server" DataTextField=name 
     DataValueField=name OnSelectedIndexChanged="strTheme_SelectedIndexChanged" 
     OnDataBound="strTheme_DataBound" DataSourceID="ThemeDataSource" 
     AutoPostBack=true RepeatDirection=Horizontal />
  8. Step 5: In the master page code-behind, such as Default.master.cs, add these methods:
  9. protected void strTheme_DataBound(object sender, EventArgs e)
    {
        strTheme.SelectedValue = Page.Theme;
    }
    protected void strTheme_SelectedIndexChanged(object sender, EventArgs e)
    {
        Session.Add("MyTheme", strTheme.SelectedValue);
        Server.Transfer(Request.FilePath);
    }
  10. Step 6: Add the BasePage class under App_Code, and specify the default theme. Here, we use "White".
  11. using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    
    
    public class BasePage : System.Web.UI.Page
    {
        protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);
            if (Session["MyTheme"] == null)
            {
                Session.Add("MyTheme", "White");
                Page.Theme = ((string)Session["MyTheme"]);
            }
            else
            {
                Page.Theme = ((string)Session["MyTheme"]);
            }
        }
    }
  12. Step 7: Inherit all the pages using the dynamic theme from BasePage:
  13. public partial class Default_aspx : BasePage
    {
    }

Happy programming!

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralReally nice article.... best demonstration.
PrathameshP
0:18 24 Dec '09  
Hi Sue,

Thanks for such nice article. Its helped me lot.

Regards,
Prathamesh.
GeneralPerfect!
netizenk
13:05 18 Jun '09  
Worked in minutes, elegant solution... thanks for sharing.
Generaldynamic web asp.net c#
magdyeltahaan
23:08 26 May '09  
help me to start with dynamic web asp.net c#
QuestionChange look and feel of portions of the page based on selected theme.
sudipta.india
22:35 24 Nov '08  
Hi all/Sue,

I would like to change look and feel of portions of the sites pages (like the borders and back color of certain div's, back color of homepage banner etc.) based on selected theme. In my case, I have primary and secondary colors which are the 7 rainbow colors. The user would be provided with a screen in which the all primary colors are displayed and the user can select any secondary color from the drop down list in front of every primary color and a checkbox which would make that theme active.

Can anybody please advise how to proceed on this.
QuestionPlease help me....
Abhishek sur
2:10 14 Nov '07  
Your article on themes is awesome. It really helped me a lot. Thanks for your post.
My problem is, I need my website to allow themes as well as use ajax, so my asp.net imagebutton will not be the server control, it will be an img and onclick of the button i want to call a javascript function. Do you know, how to load the images accordingly to html img controls based on the theme.
Thanks in advance... Please help me out. The css property background-image is not working, it shows a red cross just front of the image....

Abhishek Sur
Web Developer

GeneralDynamic Themes
webert1
11:13 25 Oct '07  
Is there a flow chart posted any place that shows dynamic themes work?
GeneralProfiles are better than sessions
wali101
7:01 17 Oct '07  
Can someone somehow make it work without the server.tranfer?

I have used profiles in place of sessions. I would like my site to remember the theme selected by the user last time.

Web.config:
===========
anonymousIdentification enabled="true"/
profile
properties
add name="Theme" defaultValue ="Green" allowAnonymous ="true"/
/properties
/profile

SelectedIndexChanged event on Master file:
==========================================
Profile.Theme = ddlTheme.SelectedValue;
Server.Transfer(Request.FilePath);

On PreInit event on Base Page:
==============================
base.OnPreInit(e);
if (!String.IsNullOrEmpty(HttpContext.Current.Profile.GetPropertyValue("Theme").ToString()))
{
Page.Theme = HttpContext.Current.Profile.GetPropertyValue("Theme").ToString();
}

Questionpostback
iron106
3:59 23 Jul '07  
The problem is, when you select an item in the radiobuttonlist. A postback event is fired.
so the page is refreshed and in the selectedindexchanged there's a server.transfer.
So the page is loaded twice in order to change the theme.
I'm sure there's a better to handle this.
QuestionHelp me! Server.MapPath
cuongnp
15:23 3 Jul '07  
My web is like this:

MyWeb
---App_Code
------Theme.cs
------ThemeManager.cs
---App_Themes
------Blue
------Red
---Child
------childpage.aspx
---default.aspx
---masterpage.master

I have problem when i use HttpContext.Current.Server.MapPath("App_Themes") function in GetThemes method in ThemeManager.cs.
It's work good when i access default.aspx page. But error when i access childpage.aspx page. At that time, HttpContext.Current.Server.MapPath("App_Themes") will refer to MyWeb/Child/App_Themes. So i can't get Theme list.

How can i fix this problem. Thank you very much!

AnswerRe: Help me! Server.MapPath
cuongnp
18:45 3 Jul '07  
I fixed it.
Thank you very much.
GeneralAny way to persist the state
Liquid Len
10:25 30 Apr '07  
Thanks for your help, I've been trying to accomplish this for a while. Odd that such a key functionality was not implemented by MS.

Is there any easy way to persist the chosen theme across multiple sessions? Without storing your choice in a database?
GeneralRe: Any way to persist the state [modified]
D. Kuzmanovic
23:33 4 Dec '08  
Modify your BasaPage::OnPreInit:
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);

if (!IsPostBack)
{
if (Session["MyTheme"] == null)
{
if ((Request.Cookies["MyTheme"] != null) &&
(Request.Cookies["MyTheme"].Value.Length != 0))
Page.Theme = Request.Cookies["MyTheme"].Value;
else Page.Theme = "White";
Session.Add("MyTheme", Page.Theme);
}
else {
Page.Theme = ((string)Session["MyTheme"]);
}
}
}

Modify your Default_aspx::strTheme_DataBound:
protected void strTheme_DataBound(object sender, EventArgs e)
{
if(!IsPostBack)
strTheme.SelectedValue = Page.Theme;
}

Modify your Default_aspx::strTheme_SelectedIndexChanged:
protected void strTheme_SelectedIndexChanged(object sender, EventArgs e)
{
Response.Cookies["MyTheme"].Value = strTheme.SelectedValue;
Response.Cookies["MyTheme"].Expires = DateTime.Now.AddYears(30);

Session.Add("MyTheme", strTheme.SelectedValue);
Server.Transfer(Request.FilePath);
}

and you will persist the state using cookies.

Hope this helps.

modified on Friday, December 5, 2008 1:53 PM

QuestionExample
M-Daraghmeh
2:07 8 Apr '07  
dear ,
do u have spacific example about this .

rgards

MDaraghmeh
.Net Developer
Jordan- Amman
00962-78-452450
m-daraghmeh@hotmail.com

Generalhamed ( Elixir )
hamedkocholo
0:22 1 Apr '07  
it,s cool
good lukeBlush
QuestionUploading a new theme/skin
XadhoomGrglblstr
9:56 29 Jan '07  
Anyone that know how or if it's possible to upload a new theme folder (w/skin file etc) without having to recompile the site and uploading /bin ?

Chao ab ordo

AnswerRe: Uploading a new theme/skin
Juba
10:06 22 Feb '07  
Just add a new theme to the Theme folder in the web server and you're done (since the theme radiobutton is populated based on this folder). Wink

"Blessed is the man who finds wisdom, the man who gains understanding."
Proverbs 3:13

GeneralNice Article
Manish Pansiniya
19:51 13 Dec '06  
Thanks Sue,

This is wat i wanted in my new project. But basically main issue is image. Is it must that we should access image by making them as image control in the skin file. Don't we put the path directly in the images or where needed.

Thank you,
Manish Pansiniya
maniish.wordpress.com[^]
Generalcool!
enteng.kabisote
16:51 7 Nov '06  

Thanks sue! Your sample is really great, it's just what I need. Big Grin
GeneralHow about using PreInit of master page?
Addisu H. Desta
7:09 31 Oct '06  
Hi,
Is it not possible to use PreInit of mater page instead of the Base page that is inherited by all pages.
Thanks for the short tips anyway!!

Addisu H. Desta
.NET Developer MCP, MCAD in .NET

GeneralRe: How about using PreInit of master page?
KoaQiu
1:07 11 Apr '07  
请参考:
http://www.codeproject.com/useritems/themeswitcher.asp?df=100&forumid=292951&select=1983760&msg=1983760
Generalvie
vievae
2:57 30 Oct '06  
in asp.net 1.1?
thxSmile
GeneralThank you! And a small tip
John Cardinal
15:06 11 Oct '06  
Nice article, my favorite kind: to the point, works and saves time.

One little tip that may or may not be dead obvious: If you have a reason to want to turn off the theming for testing, or because in our case the Telerik controls we use have a built in theme that is quite nice you just make an empty folder in your themes folder with a meaningful name like "NoTheme".

Cheers!
Generalgreat and many thanks
jackie123
9:39 15 Sep '06  
I spent some good hours trying to find out how smthng like this could be done. Thanks a lot, you look great btw. Dead :->


sean
GeneralNice article (& suggestion)
msmits
4:00 12 Jul '06  
Hi there,

As an alternative you can load a theme from global.asax.cs, like so:

Override Init() and add the following code:

PreRequestHandlerExecute += delegate(object appsender, EventArgs appargs) {
Page page = HttpContext.Current.Handler as Page;
if (page != null)
page.PreInit += delegate(object pagesender, EventArgs pageargs) {
(pagesender as Page).Theme = HttpContext.Current.Request.QueryString["theme"];
};
};

This will work with masterpages.
I've kept the code compact, this is a silly example but it (hopefully) illustrates the point Wink

Cheers,
Michel
GeneralGreat Article
gweeter
10:46 30 Jun '06  
Thank you for posting this information.   I looked in several places, but none had this approach, which is what I was looking for.

I do have one thing to add for anyone else who might want to change the StyleSheetTheme instead of just the Theme.
In the Base.cs class I had to override the StyleSheetTheme property instead of the OnPreInit method.

Like this:

      private string myTheme;
      public override string StyleSheetTheme
      {
            get
            {
                  if (Session["MyTheme"] == null)
                  {
                        return "ThemeName";
                  }
                  else
                  {
                        return (string)Session["MyTheme"];
                  }
            }
            set
            {
                  myTheme = value;
            }
      }

Hope that helps any future visitors!


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