rel="File-List" href="file:///C:%5CDOCUME%7E1%5C%E8%B5%96%E5%BC%BA%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml">
ASP.NET主题可以让网站的页面风格一致。使用它可以同时控制HTML元素和ASP.NET控件在页面上的皮肤。
主题不同于母版页。母版页可以在网站的多个页面间共享内容,而主题的作用是为了控制内容的皮肤。
1 创建主题
在名为“App_Themes”的应用程序的文件夹中新建文件夹就可以创建主题。在App_Themes中添加的每个文件夹都代表一个主题。
如果App_Themes文件夹不存在,可以创建一个。但是一定要在应用程序的根目录中创建。
注:当使用Visual Web Developer时,可以通过以下方式创建一个新的主题文件夹:在解决方案资源管理器视图中,在项目的右键菜单上选择“Add ASP.NET Folder(添加ASP.NET文件夹)”,然后选择“Theme(主题)”即可。
一个主题文件夹中有几种不同类型的文件,包括图片和文本文件。可以通过在主题文件夹中添加多个子文件夹来组织主题文件夹的内容。
在主题文件夹中比较重要的文件类型是:
皮肤文件
CSS文件
2 在主题中添加皮肤
一个主题可能包含一个或多个皮肤文件。可以通过皮肤来修改所有具有皮肤效果的ASP.NET控件的属性。
例如,将Web应用程序中所有的TextBox控件的背景色设为黄色并选择dotted作为它的边框样式。如果将代码清单1中的文件添加到Simple主题中(App_Themes/Simple文件夹),就可以在所有的页面中通过Simple主题来修改页面中所有TextBox控件的皮肤。
清单1:Simple/TextBox.skin
<asp:TextBox BackColor="Yellow" BorderStyle="Dotted" Runat="Server" />
建议采用以下命名规则:皮肤文件名称和待修改的控件名称一样,在加上皮肤的扩展名称。
注:不能给用户控件的属性应用皮肤。然而,可以给用户控件中包含的控件应用皮肤。
清单2:ShowSkin.aspx
<%@ Page Language="C#" Theme="Simple" %>
<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Show Skin</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox runat="server" />
</div>
</form>
</body>
</html>
注意,代码清单2的页面的<%@ Page %>指令中有一个Theme属性。Simple主题就是通过这个属性应用到页面的。
注:默认情况下,所有的控件属性都是可以主题化的(可以在皮肤文件中修改)。但是,一些控件属性由Themeable(False)属性,可以使用这个属性来禁用主题。
2.1 创建命名皮肤
上面创建的是默认皮肤。默认皮肤可以应用在合适类型的控件的每个实例上,比如应用在TextBox控件的每个实例上。
同时也可以创建命名皮肤。在创建命名时,可以指定什么时候应用该皮肤。如果需要将必填的表单字段外框设为红色,就可以创建一个命名皮肤然后再特定得TextBox控件上应用这些皮肤。
代码清单3:TextBox.skin
<!--默认皮肤-->
<asp:TextBox BorderStyle="Double" BorderWidth="5px" Runat="Server" />
<!--命名皮肤-->
<asp:TextBox SkinID="DashedTextBox" BorderStyle="Dashed" BorderWidth="5px" Runat="Server" />
在一个主题中,每一个控件只能有一个默认皮肤。但是,可以在主题中包括多个命名皮肤。每个命名皮肤的名称必须唯一。
代码清单4:ShowNamedSkin.aspx
<%@ Page Language="C#" Theme="Simple" %>
<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Show Skin</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtFirstName" SkinID="DashedTextBox" runat="server" />
<br /><br />
<asp:TextBox ID="txtLastName" runat="server" />
</div>
</form>
</body>
</html>
2.2 Themes与StyleSheetThemes
当在页面中应用主题时,主题中的控件属性会重写页面中的已有控件属性。也就是说,皮肤文件中的属性会重写页面中的属性。
主题文件的这个默认行为在修改已有网站的时候非常有用。可以使用它来重写页面上控件的所有皮肤属性。
但是,有时候连Skin属性也需要重写。比如,要修改整个站点中的Label控件,将它们的背景颜色改为橙色,但是一个Label控件除外。这时,如果能重写控件的Skin属性就很方便了。
将主题应用到含有StyleSheetTheme属性,而不是Theme属性的页面上就可以重写Skin属性。
2.3 禁用主题
每个ASP.NET控件都包含名为EnableTheming的属性。可以使用这个属性来阻止页面中的特定控件应用皮肤。
2.4 在Web配置文件中注册主题
在页面中应用主题的方法,除了在每个页面中添加Theme或者StyleSheetTheme属性外,还可以在Web属性文件中注册主题,使网站的所有页面都可以使用主题。
代码清单5:Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<pages theme="Simple" />
</system.web>
</configuration>
除了使用Theme属性外,还可以使用StyleSheetTheme属性来对应用程序中的页面应用主题。例如使用StyleSheetTheme属性,就可以重写页面中通过Skin属性指定的主题。
3 在主题中添加CSS
除了使用皮肤文件,也可以使用CSS来控制页面上HTML元素和ASP.NET控件的皮肤。如果在主题文件夹中添加CSS文件,则在页面应用主题时也会自动应用CSS。
代码清单6:SimpleStyle.css
html
{
background-color:Gray;
font:14px Georgia ,Serif;
}
.content
{
margin:auto;
width:600px;
border:solid 1px black;
background-color:White;
padding:10px;
}
hl
{
color:Gray;
font-size:18px;
border-bottom:solid 1px orange;
}
lable
{
font-weight:bold;
}
input
{
background-color:Yellow;
border:double 3px orange;
}
.button
{
background-color:#eeeeee;
}
如果在名为StyleTheme的主题文件夹中添加SimpleStyle.css文件(App_Themes文件夹下的StyleTheme文件夹),这个CSS将会自动应用到代码清单7中的页面。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowSimpleCSS.aspx.cs" Inherits="ThemeDemo.ShowSimpleCSS" Theme="StyleTheme" %>
<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Show Simple CSS</title>
</head>
<body>
<form id="form1" runat="server">
<div class="content">
<h1>Registration Form</h1>
<asp:Label ID="lblFirstName" Text="First Name:" AssociatedControlID="txtFirstName" runat="server" />
<br />
<asp:TextBox ID="txtFirstName" runat="server" />
<br /><br />
<asp:Label ID="lblLastName" Text="Last Name:" AssociatedControlID="txtLastName" runat="server" />
<br />
<asp:TextBox ID="txtLastName" runat="server" />
<br /><br />
<asp:Button ID="btnSubmit" Text="Submit Form" CssClass="button" runat="server" />
</div>
</form>
</body>
</html>
CSS用来对代码清单7中的几个HTML元素进行样式设置。例如,样式表将页面背景色设为灰色,并将<div>标签的内容设为居中。
因为ASP.NET控件也会呈现为HTML元素,所以样式表也可以对由ASP.NET的Label控件、TextBox控件和Button控件呈现的HTML元素进行样式设置。一个Label控件会输出为一个HTML<label>标签,样式表将所有的<label>标签格式化为粗体。TextBox控件和Button控件的输出为HTML<input>标签,样式表将修改<input>标签的边框样式和背景颜色。
使用CSS的好处是使加载页面的速度更快。在外部的样式表中保存的内容越多,在每次页面请求时需要加载的内容就越少。浏览器可以加载缓存外部样式表的内容并对Web应用程序中的所有页面应用样式表。
如果通过修改控件属性来修改控件皮肤,那么在每次页面请求时,多余的内容都会被加载到浏览器中。
使用皮肤文件和修改控件属性没有区别。使用皮肤也会使页面变得臃肿。举例来说,如果给Label控件创建一个皮肤,当每个页面的Label控件输出时,皮肤文件中的Label的属性必须和每个页面中的Label控件进行合并。
3.1 在主题中添加多个CSS
可以在主体文件夹中添加任意多个CSS文件。在主题中添加多个CSS后,在主题应用到页面时,所有的CSS也都会应用到页面。
外部样式表连接到页面的顺序非常重要。应为一个样式表中的样式规则可以被其他样式表中的样式规则重写。
在主题中添加多个样式表后,样式表应用到页面的顺序是按字母排序的(根据样式表文件名)。
4 创建全局主体
可以在一个Web服务器端上的多个程序之间共享同一个主题。全局主题包括皮肤文件和CSS文件。在创建一个企业规模的站点并需要将页面表现方式应用到企业中的所有应用程序时,全局主题十分有用。
在创建全局主题的方法是将主题文件夹保存在以下路径:
WINDOWS/Microsoft.NET/Frameword/[version]/ASP.NETClientFiles/Themes
将主题文件添加在此路径后,就可以马上在基于文件系统的网站中使用这个主题。如果需要在基于HTTP的网站上使用这个主题,还需要额外的步骤:将主题文件夹添加在以下路经:Inetput/wwwroot/aspnet_client/system_web/[version]/Themes
手工将主题文件复制到此文件夹,或者在命令行中通过以下方式使用aspnet_regiis工具:
Aspnet_regiis –c
Aspnet_regiis工具在Windows/Microsoft.NET/Frameword/[version]文件夹中。打开命令提示并导航到这个文件夹就可以使用这个工具。
5 动态应用主题
通过处理页面的PreInit事件可以在页面中动态应用主题。在请求页面时,这是第一个被触发的事件。在其后的Load或PreRender等事件中是不能动态应用主题的。
例如:代码清单8、9、10中就能通过用户在页面的点击来应用绿色主题或红色主题
代码清单8:App_Themes/GreenTheme/GreenStyle.css
html
{
background-color:Green;
font:14px Georgia ,Serif;
}
.content
{
margin:auto;
width:600px;
border:solid 1px black;
background-color:White;
padding:10px;
}
h1
{
color:Green;
font-size:18px;
border-bottom:solid 1px orange;
}
代码清单9:App_Themes/RedTheme/RedStyle.css
html
{
background-color:Red;
font:14px Georgia ,Serif;
}
.content
{
margin:auto;
width:600px;
border:solid 1px black;
background-color:White;
padding:10px;
}
h1
{
color:Red;
font-size:18px;
border-bottom:solid 1px orange;
}
代码清单10:DynamicTheme.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicTheme.aspx.cs" Inherits="ThemeDemo.DynamicTheme" %>
<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_PreInit(object sender, EventArgs e)
{
if (Request["theme"] != null)
{
switch (Request["theme"])
{
case "Green":
Profile.UserTheme = "GreenTheme";
break;
case "Red":
Profile.UserTheme = "RedTheme";
break;
}
Theme = Profile.UserTheme;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Dynamic Theme</title>
</head>
<body>
<form id="form1" runat="server">
<div class="content">
<h1>Dynamic Theme</h1>
Please select a Theme:
<ul>
<li><a href="DynamicTheme.aspx?theme=Green">Green Theme</a></li>
<li><a href="DynamicTheme.aspx?theme=Red">Red Theme</a></li>
</ul>
</div>
</form>
</body>
</html>
通过页面的Theme属性,特定主题可以应用到此页面。通过在PreInit事件中将主题名称(文件夹名称)赋给Theme属性,主题就会应用到页面。
注意,被选择的主题保存在Profile对象中。当把信息保存在Profile对象中时,在浏览器多个站点时这个信息仍然可以保留。所以如果用户选择了一次自己喜欢的主题,那么当用户在以后再次回到此站点时仍然会应用此主题。
代码清单11中的Web配置文件中定义了Profile
<system.web>
<profile>
<properties>
<add name="UserTheme"/>
</properties>
</profile>
</system.web>
因为在PreInit事件触发后,控件树并没有创建完成,所以不能引用页面中的控件。