ASP.NET 2.0 中新增加了 Theme 的功能,它的出现能让网站实现换肤更加容易。Theme 的实现包括:CSSSkinMasterPage

  CSS 是用于控制所有 HTML 标记的外观。
  Skin 是用于控制所有 ASP.NET 服务器调整的外观,并且可以通过属性 cssClass 定义它的 CSS 样式。
  MasterPage *.aspx 页面模版,不过它没有被定义到 Theme 中。
  
创建 Theme 的例子
  1、在 Web 项目中创建 App_Themes 目录。它是预定义的目录,ASP.NET 2.0 会自动识别其目录下的 Theme
  2、在 App_Themes 目录创建 orangeThemeBlueTheme 两个子目录。
  3、为 App_Themes 下的每个子目录添加 Skin 文件,如 Control.Skin ASP.NET 2.0 会自动分析每一个 Skin 文件,在这里的命名只需要为了开发时方便分类。
  4、也可以为 App_Themes 下的每个子目录添加 CSS 文件。ASP.NET 2.0 也会自动将每一个 CSS 文件添加到每一个使用此样式的页面中去。(在用到了这个theme的页面中自动会应用你的.css的)

在页面中使用 Theme
(指定好 Theme 之后所有的外观都会使用 Skin 中定义的。你也可以指定控件的 SkinID 来定义单独外观。)  

1.      1个页面中应用Theme

如果想在某1个页面中应用Theme,直接在aspx文件中修改<%@ Page Theme="..." %>,比如你想这个页面应用OrangeTheme theme,设置<%@ Page Theme=" OrangeTheme " %>OK

2.         在所有页面应用同1Theme

如果想到在整个网站应用某个 Theme 就需要在 Web.Config 定义。
<configuration>
   <system.web>
   <pages theme="OrangeTheme" />
   </system.web>
</configuration>
这样的定义相当于默认一个 Theme 在所有网站文件中,使用时仍可以为每个页面定义 Theme 。  

3.         如果想用编程方式定义 Theme 必需在 Page_PreInit事件中处理,如下:
  void Page_PreInit(object sender, EventArgs e)
  {
   Page.Theme = Request["ThemeName"];
   如果需要以编程的方式为 Page 载入 MasterPage 文件,也需要在此定义。
   this.MasterPageFile = Request["MasterPageFile"];
  }

 

SKIN 文件样式

OrangeTheme 主页的 Control.Skin 文件中定义如下:
  注意:只能指定外观属性,不能指定如 AutoPastback 等属性。
  默认未命名的 Skin 将会为所有 TextBox 类型定义外观。
  <asp:TextBox BackColor="Orange" ForeColor="DarkGreen" Runat="Server" />
  <asp:Button BackColor="Orange" ForeColor="DarkGreen" Font-Bold="True" Runat="Server" />
  已经命名 SkinID 的将可以为指定 TextBox 类型定义外观。
  <asp:TextBox SkinID="Title" BackColor="Orange" ForeColor="DarkGreen" Runat="Server" />

让控件不应用Theme

1.      有时我们希望某1个控件不应用.skin中的风格,这时你只需设置控件的EnableTheming属性为false就可以了。

2.      也许你还想不同的控件显示不同的风格,你只需设置控件的SkinID属性就可以,见下面的实例:

 1.skin

<asp:label runat="server" font-bold="true" forecolor="Red" />
<asp:label runat="server" SkinID="Blue" font-bold="true" forecolor="blue" />

deafult.aspx

<asp:Label ID="Label2" runat="server" Text="Hello 2" SkinID="Blue" /><br />
             <asp:Label ID="Label3" runat="server" Text="Hello 3" /><br />
 
运行后就会发现2label显示的风格不一样了。

 

风格顺序
前面已经说了在aspx文件头使用 <%@ Page Theme="..." %> 来使用theme,而用这个方法应用theme中的风格将会覆盖你写在aspx中的控件属性style。比如:
 1.skin

<asp:Label Font-Bold="true" ForeColor="Red" runat="server" />
default.aspx

      <asp:Label ID="Label1" runat="server" Text="Hello 1" /><br />
      <asp:Label ID="Label2" runat="server" Text="Hello 2" ForeColor="blue" />
 
运行结果,所有的labelforecolor都为red

 而使用<%@ Page StyleSheetTheme="..." %>应用theme就不会覆盖你在aspx文件中写的属性style

控件应用style属性的顺序如下:
a
StyleSheetTheme引用的风格
b
、代码设定的控件属性(覆盖StyleSheetTheme)
c
Theme引用的风格(覆盖前面2)

 

后台代码轻松为网站换肤的实例

aspx文件或web.config中应用theme,而在blog这样的每个用户都有不同的skin的网站中用上面的方法来实现换skin显然是不方便的。

 

怎么在后台代码中动态的引用theme来解决上面的情况,theme必须在page被请求的最早期就应用上,所以我们必须在Page_PreInit事件中写代码,代码很简单,就1句:
        Page.Theme = "..."; 
这里我们只要从数据库中去读取每个用户设置的不同theme名就可以轻松实现每个用户都有不同的skin了。

 

读取Theme值的代码

System.Web.Configuration.PagesSection ps = (System.Web.Configuration.PagesSection)System.Configuration.ConfigurationManager.GetSection("system.web/pages");
TextBox1.Text = ps.Theme;

 

动态设置全局theme

Global.asax里写上Page_PreInit

Global.asax的代码如下:
<%@ Application Language="C#" %>
<script runat="server">
void Page_PreInit(object sender, BrockAllen.Web.PageEventArgs e)
{
string t = HttpContext.Current.Profile.GetPropertyValue("Theme") as string;
if (t != null && t.Length > 0)
{
e.Page.Theme = t;
}
else
{
e.Page.Theme = "Default";
}
}
</script>