Dynamic Theme Switching
I think it is usually a good design practice, with
Framework 2.0 applications, to control as much as possible
with themes that
consist of a CSS file, a Skin file, and whatever graphic files are
required. This allows for
an entire site to change its appearance by
just changing the theme. I went a step beyond that and enabled this
site to allow dynamic theme changes from the dropdown box on the page heading.
One of the choices is “NoTheme” so you
can see the site as it is with no CSS
or Skin applied. I plan to go a step further soon and implement memory
of the last theme the user chose so it can be redisplayed at the users’ next
visit using the new Atlas
ProfileScriptService.
Implementing
dynamic theme switching entails the following …
First develop all
of the themes you want and put them all under the App_Themes folder in your
ASP.Net project.
Create a class, call it SwitchPage, and put it in
the App_code folder. It would look like this…
public class
SwitchPage : System.Web.UI.Page
{
protected override
void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if
(Session["TheTheme"] == null)
{
Session.Add("TheTheme",
"Primary");
Page.Theme =
((string)Session["TheTheme"]);
}
else
{
Page.Theme =
((string)Session["TheTheme"]);
}
}
}
In my case “Primary” is the name of
my theme that I want to always display first. What this does is set the
page,
to which this class belongs, to whatever is in
Session[“TheTheme”]. The trick to make this work is to change the
inherit statement on all of you aspx pages to inherit from SwitchPage
instead of System.Web.UIPage.
The theme DropDown has to be
connected to an ObjectDataSource that is bound to the following C# class that
returns
an List object…
public class
ThemeSupplier
{
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;
}
}
ThemeSupplier is helped by the following helper
class...
public class Theme
{
private
string _name;
public string Name
{
get { return _name;
}
set { _name = value;
}
}
public Theme(string
name)
{
Name
= name;
}
}
Finally the following two
events make the switch actually happen…
protected void
ddlTheme_DataBound(object sender, EventArgs e)
{
ddlTheme.SelectedValue =
Page.Theme;
}
protected void
ddlTheme_SelectedIndexChanged(object sender, EventArgs e)
{
Session.Add("TheTheme",
ddlTheme.SelectedValue);
Server.Transfer(Request.FilePath); //just start the page
over
}
I use a program named TopStyle to do
CSS files. I prefer it to Visual Studio but you might
not.
The trick to doing Skin files is to add a page, call it
Scratch.aspx, to your project. Drag, for instance, a GridView
onto it
and then use VS design time to make it look just like you want your gridviews
for a given theme to look. Then
paste the definition into your .Skin
file and remove the id entry. That way you are letting VS do a lot of the
work
for you.