Sunday, March 01, 2015

[ ASP.Net ] - Dynamically applying web themes

1. Introduction

A theme allows setting the properties of server-side controls and by making use of themes one can provide consistency in the format of the entire website. That means, all the controls maintain some uniformity; Say for example all the buttons in the website appears with a red border around it. A theme should have at least one skin file in it. A website can have one or more themes and by applying the theme, entire web site’s visual appearance changes in seconds. For example, let us say a website sells music CDs and the website wants to change its appearance every charismas and go back normal after Jan-05. This can be done easily with two themes - Normal, Xmas.



2. Creating a Theme

In ASP.net, all the themes are organised under App_themes. To create a theme, right-click on your project name in the solution explorer, then pick theme under Add Asp.net Folder as shown in the below picture:

Fig.1: Creating Theme Folder



 Once the theme is created you can add skin and Cascading Stylesheet (CSS) files to it. The skin file supplies formatting information for the server side controls whereas cascading style sheet provides formatting information for HTML element. So the formatting from the skin is applied on the server and CSS formatting is applied on the client browsers. CSS and skin files can be added using the Add New item dialog, which is shown below:

Fig 2: Adding Skin and Style Sheet

In the below video shows:
1) Creating a theme
2) Creating a CSS
3) Creating Skin file
4) Assigning the theme to a page

Video 1: Creating a Theme




3. SkinId usage

In the previous video you saw, theme Normal is created and tested on the Default.aspx page. We placed three label controls on the web form and all the label has the same visual appearance. Suppose, if we want to add header label which appears different from all other labels in the same form, we should start using Skin Id. A skin file can have only one formatting entry for a specific control type. That means formatting details for button appears once, formatting detail for label appears once and so on. In order to have two formatting entries for a specific control, skin ids are used. In our case, we want the normal theme should have the capability of holding two different labels formatting one for header label and another one for normal labels. The control in the web page refers this skin id to have specific formatting details from the skin file of the theme.

In the below video, I created a page which has three labels. One takes header label formatting from the skin file and other two labels take normal formatting detail from the skin file.

Video 2: Using Skin Id





4. About the Example

The screenshot of this article’s example application is shown below:

Fig 3: Example Pages with Web Themes settings

When you start the website, Home Page is displayed. You can select a product and submit to move to the Order Confirmation page. The order confirmation page has labels to provide order confirmation and the same page also has a link called “Home” to navigate back to the homepage. From the homepage, you can navigate to the Web Admin Page where you can set the theme for the application. You can select a theme in the web admin page, and apply that theme to the whole site (In our case it contains only three page) by clicking the applied button. From the web admin page, you can go to the main webpage by using the home link.

All three pages use two themes named Ocean and Desert. By default, when the site is launched for the first time, no themes will be applied and you should go to the web admin page to apply a theme. The code behind in the web admin page uses the session variable for demo purpose. You should use application variables for real websites.



5. Ocean and Desert Themes


The Example website has three pages and two themes. These two themes can be applied dynamically to all three pages and thereby maintaining the consistency among the pages. Below picture shows solution explorer view of the Example:

Fig 4: Folder of the Example Web App

Note each theme contains a Skin file and cascading style sheet in it. The image folder contains images used by the default page. Making of these two themes and skin file is discussed in the below video:

Video 3: Ocean and Desert Theme





6. Code Behind – Web Admin Page



01) The CheckedChanged event for the radio buttons are handled and in the handler code, based on the check state of the radio buttons, theme name is stored in a Session variable called PgTheme. The session variable holds the value among the pages for the current web session. In the real world, the theme will be stored on application global as it is a web setting set by the admin of the web page.  The code for this is shown below:

//Sample 1.0 : Set theme session variable when theme selected
protected void radThemeOcean_CheckedChanged(object sender, EventArgs e)
{
    if (radThemeOcean.Checked == true)
    {
        Session["PgTheme"] = "Ocean";
    }
    else
    {
        Session["PgTheme"] = null;
    }
}

protected void radThemeDesert_CheckedChanged(object sender, EventArgs e)
{
    if (radThemeDesert.Checked == true)
    {
        Session["PgTheme"] = "Desert";
    }
    else
    {
        Session["PgTheme"] = null;
    }
}


02) The page uses a function called SetSkins, which actually sets SkinId for the label contained in this Web Admin webpage.

//4.0 Set SkinIds
protected void SetSkins(String Theme)
{
    if (Theme == "Ocean")
    {
        LblTitle.SkinID = "PT";
        LblOcean.SkinID = "NormalLBL";
        LblDesert.SkinID = "NormalLBL";
    }
    else if (Theme == "Desert")
    {
        LblTitle.SkinID = "DPT";
        LblOcean.SkinID = "DNormalLBL";
        LblDesert.SkinID = "DNormalLBL";
    }
}


03) When “Apply” button is clicked, we make a call to the Server.Transfer. This function call re-executes the page and page life cycle starts again. When the page render happens now you will see the new theme in effect. Below is the code:

//3.0 Re-execute the current page
protected void Button1_Click(object sender, EventArgs e)
{
    Server.Transfer(Request.FilePath);
}


04) Finally, we set the page theme and skin ids to the page during the page pre-initialization. First, we make sure the session variable is not empty and then we set the theme name taking it from the “PhTheme” session variable. After setting the theme, we set the skin ids by making a call to the SetSkins function.

//2.0 Set Page theme when before page initialized
protected void Page_PreInit(object sender, EventArgs e)
{
    if (Session["PgTheme"] == null)
        Page.Theme = null;
    else
    {
        String theme = Session["PgTheme"].ToString();
        Page.Theme = theme;
        SetSkins(theme);
    }
}


7. Code Behind – for another page

In the other two pages, we are setting the theme during page initialization. The theme is taken from the current session variable PgTheme (For demo purpose) and applied to the page before actual page render happens. Below is the code for both Default.aspx and Confirm.aspx pages:

Confirm.aspx

public partial class Confirm : System.Web.UI.Page
{
    //7.0 Set the the skin ids based on theme
    protected void SetSkins(String Theme)
    {
        if (Theme == "Ocean")
        {
            lblPageTitle.SkinID = "PT";
            lblInformation.SkinID = "NormalLBL";
        }
        else if (Theme == "Desert")
        {
            lblPageTitle.SkinID = "DPT";
            lblInformation.SkinID = "DNormalLBL";
        }
    }

    //8.0 Set theme during page initialization
    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Session["PgTheme"] == null)
            Page.Theme = null;
        else
        {
            String theme = Session["PgTheme"].ToString();
            Page.Theme = theme;
            SetSkins(theme);
        }
    }
}

Default.aspx

public partial class _Default : System.Web.UI.Page
{
    //5.0 Set Skin function for Default Page
    protected void SetSkins(String Theme)
    {
        if (Theme == "Ocean")
        {
            lblPageTitle.SkinID = "PT";
        }
        else if (Theme == "Desert")
        {
            lblPageTitle.SkinID = "DPT";
        }
    }

    //6.0 Set theme during page initialization
    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Session["PgTheme"] == null)
            Page.Theme = null;
        else
        {
            String theme = Session["PgTheme"].ToString();
            Page.Theme = theme;
            SetSkins(theme);
        }
    }
}

The below video shows how the site appearance changed by the web admin page by making the application themes and setting it dynamically.


Video 4: Dynamically changing application theme




 Source Code : Download
Like this site? Tell it to your Firend :)