第8章 主题
主题是在CSS的基础上推出的一种控制页面一致性样式的技术。母版页用来定义布局,主题则用来控制页面内容。使用主题可以控制页面中HTML元素和ASP.NET控件的呈现,为不同控件的不同属性设置皮肤。本章将给大家详细讲解主题的创建和主题的应用,以及如何解决在应用主题时遇到的问题。
8.1 主题简介
主题是定义网站中页和控件的外观的属性集合,它负责完成对Web应用程序的页面、整个Web应用程序或者服务器上的所有Web应用程序的外观应用。本节简单了解一些主题。
8.1.1 组成元素
知识点讲解:光盘\视频讲解\第8章\组成元素.wmv
主题由一些元素组成:皮肤、层叠样式表、图形和其他资源。各组成元素具体说明如下。
- 皮肤:皮肤文件是拥有文件扩展名.skin并且包含控件类型的属性设定集。控件的皮肤设定集有点像控件的标记,只是皮肤设定集中只包含作为主题的一部分而被设定的属性集。皮肤分为默认皮肤和命名皮肤。
- 层叠样式表:主题中也可以包括层叠式样式表单(.css文件)。当把一个.css文件保存到主题目录中的时候,该样式表单会自动作为主题的一部分被应用。可以在主题目录中使用扩展名为.css的文件来定义样式表单。主题中可以包含一个或多个层叠样式表。
- 图形和其他资源:主题中也可以包括图形和其他资源(如脚本文件或者声音文件)。通常情况下,主题的资源文件与该主题的皮肤文件位于同一个文件夹下。但也可以把资源文件保存到主题目录之外的位置。当使用了波浪号(~)语法来引用资源文件时,应用程序会自动查找图片位置。
注意:一个主题在最小范围内至少包含皮肤定义。
8.1.2 作用范围
知识点讲解:光盘\视频讲解\第8章\作用范围.wmv
开发人员可以为单个Web应用程序定义主题,也可以为Web服务器中的所有应用程序定义全局性的主题。主题被定义之后,就可以通过使用@Page指令的Theme或者StyleSheetTheme参数放置到单独的页面中,或者是通过设置配置文件中的<pages>元素应用到应用程序中的所有页面。
1. 页面主题
页面主题就是在网站\App_Themes目录下的一个子目录。该子目录中包含控件皮肤、层叠样式表文件、图形文件和其他资源文件。
2. 全局主题
全局主题可以被应用到服务器中的所有网站。如果你在同一个服务器上维护着多个网站,那么就可以使用全局主题统一所有网站的外观。
注意:全局主题和页面主题一样,也包括属性的设定集、样式表设定集和图形集。区别是全局主题被保存在Web服务器的全局\Themes目录中。服务器上的任何网站和任何页面都可以应用全局主题。
3. 主题设定的优先序列
在处理使用母版页的ASP.NET应用程序时,注意Page和Master指令都包含EnableTheming属性。如果在ASP.NET应用程序的Web.config文件中定义了主题,而母版页中使用EnabelTheming属性指定禁用主题,那么若内容页没有指定主题,就采用母版页的设置,不用主题。即使在内容页设置了EnableTheming属性,也优先采用母版页指定的EnableTheming属性。详细请看表8.1所示。
表8.1 主题设定的优先序列
8.2 创建主题
知识点讲解:光盘\视频讲解\第8章\创建主题.wmv
为了创建主题,首先需要创建一个名为App_Themes的主题文件夹用来存放主题。该文件夹必须位于应用程序的根目录中。在该文件夹中可以存放多个主题设置。每个主题必须用一个单独的子文件夹进行存放。
在创建主题过程中,必须注意主题和主题文件夹的命名。主题文件夹在后台会自动编译为一个新类。因此不能把主题命名为项目中已经存在的类名,会发生冲突。
一个主题可以包含一个或者多个皮肤文件。皮肤文件允许修改服务器控件中任何影响其皮肤呈现的属性。Visual Studio 2012没有提供对皮肤文件设计时的支持,因此为了对特定的服务器控件创建皮肤,开发人员需要先在页面中设计好外观,然后复制到皮肤文件中。对服务器控件的外观定义与普通的Web页面相似,唯一不同的是不能使用ID属性。
【示例8-1】下面演示创建主题的方式。
(1)创建一个网站,命名为“创建一个主题”。
(2)在解决方案资源管理器中的网站上单击右键,在弹出的快捷菜单中选择“添加ASP.NET文件夹”|“主题”命令。Visual Studio 2012会添加一个名为App_Themes的文件夹,并在该文件夹下添加一个命名为“主题1”的子文件夹。将“主题1”文件夹重命名为MyTheme。
(3)在MyTheme文件夹上单击鼠标右键,在弹出的快捷菜单中选择“添加新项”命令。在打开的“添加新项”对话框中选择“外观文件”选项,命名为SkinFile.skin,如图8.1所示。然后单击“添加”按钮,Visual Studio 2012将自动进入皮肤文件窗口。
图8.1 “添加新项”对话框
在SkinFile.skin文件中,简单地定义3个控件的前景色和背景色,代码如下所示:
示例8-1:创建主题
源码路径:光盘\源文件\Chapter8\示例8-1\创建一个主题\App_Themes\MyTheme\SkinFile.skin
(4)添加一个ASP.NET页面来应用这个主题,命名为Default.aspx。在该Web页面中添加一个ListBox控件、一个TextBox控件和一个Button控件,声明代码如下:
示例8-1:创建主题
源码路径:光盘\源文件\Chapter8\示例8-1\创建一个主题\Default.aspx
然后单击Default.aspx页面空白处,在“属性”窗格中选择DOCUMENT属性,然后找到其中的Theme属性,选择前面创建的MyTheme主题文件夹,如图8.2所示。
图8.2 选择主题
选择好主题后,在页面源代码的@Page指令声明中,可以看到Visual Studio 2012自动在Default.aspx页面中添加了Theme属性,代码如下:
示例8-1:创建主题
源码路径:光盘\源文件\Chapter8\示例8-1\创建一个主题\Default.aspx
运行结果如图8.3所示。
图8.3 运行结果图
在该示例中,当为页面应用主题时,首先ASP.NET将检查页面上的控件,然后在皮肤文件中查找是否具有匹配的控件。如果匹配,皮肤文件中的属性设置会自动覆盖默认的属性设置。这种定义皮肤的方式称为默认皮肤。
8.3 在主题中应用皮肤、CSS和图片
使用主题可以控制页面中HTML元素和ASP.NET控件的呈现。主题由一些元素组成:皮肤、层叠样式表、图形和其他资源。因此,我们可以通过在主题中应用皮肤、CSS文件和图片等使网站更加美观。本节我们来学习如何在主题中应用皮肤、CSS和图片。
8.3.1 在主题中应用命名皮肤
知识点讲解:光盘\视频讲解\第8章\在主题中应用命名皮肤.wmv
皮肤分为默认皮肤和命名皮肤。示例8-1中的皮肤是默认皮肤,有时不够灵活。当在一个页面中,有几个相同类型的控件,要将它们分类并用不同的皮肤进行表示时,命名皮肤就很容易解决这种问题。
要创建命名皮肤时,只需要在皮肤文件的定义中使用SkinID指定一个皮肤名称即可。可以为相同的控件创建多个具有不同SkinID的皮肤。
注意:在皮肤文件中,可以将匿名的皮肤和指定的皮肤放在一起使用。让指定SkinID的控件应用命名皮肤,未指定的则应用默认皮肤。
【示例8-2】下面演示创建命名皮肤的方式。
(1)创建一个网站,命名为“创建命名皮肤”。
(2)在解决方案资源管理器中的网站上单击右键,在弹出的快捷菜单中选择“添加ASP.NET文件夹”|“主题”命令。Visual Studio 2012会添加一个名为App_Themes的文件夹,并在该文件夹下添加一个命名为“主题1”的子文件夹。将“主题1”文件夹重命名为MyTheme。
(3)在MyTheme文件夹上单击鼠标右键,在弹出的快捷菜单中选择“添加新项”命令。在打开的“添加新项”对话框中选择“外观文件”选项,命名为SkinFile.skin。然后单击“添加”按钮,Visual Studio 2012将自动进入皮肤文件窗口。在SkinFile.skin文件中添加几个命名的主题,具体代码如下:
示例8-2:创建命名皮肤
源码路径:光盘\源文件\Chapter8\示例8-2\创建命名皮肤\App_Themes\MyTheme\SkinFile.skin
指定了SkinID的控件将不会自动应用默认皮肤。为了应用命名皮肤,需要设置控件的SkinID属性来匹配特定的皮肤。开发人员可以在“属性”窗格的下拉列表框中选择合适的皮肤,如图8.4所示。
图8.4 “属性”窗格
为每个控件选择好皮肤后,在页面源代码的@Page指令声明中,可以看到Visual Studio 2012在Default.aspx页面中自动为每个控件添加了SkinID属性,代码如下:
示例8-2:创建命名皮肤
源码路径:光盘\源文件\Chapter8\示例8-2\创建命名皮肤\Default.aspx
运行结果如图8.5所示。
图8.5 运行结果图
在该示例中,使用SkinID属性为每个控件皮肤命名。命名皮肤和默认皮肤的唯一不同点是需要为命名皮肤指定一个SkinID属性,用于命名一个皮肤。
8.3.2 在主题中应用CSS文件
知识点讲解:光盘\视频讲解\第8章\在主题中应用CSS文件.wmv
ASP.NET还提供了在主题中使用CSS文件的功能。使用样式表可以控制服务器控件和HTML元素的呈现形式。在主题中添加了CSS文件后,样式表将自动应用到所有页面。
【示例8-3】下面演示在主题中应用CSS文件的方式。
(1)创建一个网站,命名为“在主题中应用CSS文件”。
(2)在解决方案资源管理器中的网站上单击右键,在弹出的快捷菜单中选择“添加ASP.NET文件夹”|“主题”命令。Visual Studio 2012会添加一个名为App_Themes的文件夹,并在该文件夹下添加一个命名为“主题1”的子文件夹。将“主题1”文件夹重命名为MyTheme。
(3)在MyTheme文件夹上单击鼠标右键,在弹出的快捷菜单中选择“添加新项”命令。在打开的“添加新项”对话框中选择“样式表”选项,命名为StyleSheet.css,如图8.6所示。然后单击“添加”按钮,Visual Studio 2012将自动进入皮肤文件窗口。
图8.6 “添加新项”对话框
在StyleSheet.css文件中添加代码来控制页面外观,代码如下:
示例8-3:在主题中应用CSS文件
源码路径:光盘\源文件\Chapter8\示例8-3\在主题中应用CSS文件\App_Themes\MyTheme\StyleSheet.css
(4)添加一个ASP.NET页面来应用这个主题,命名为Default.aspx。在该Web页面中添加内容,代码如下:
示例8-3:在主题中应用CSS文件
源码路径:光盘\源文件\Chapter8\示例8-3\在主题中应用CSS文件\Default.aspx
然后单击Default.aspx页面空白处,在“属性”窗格中选择DOCUMENT属性,然后找到其中的Theme属性,选择前面创建的MyTheme主题文件夹。选择好主题后,在页面源代码的@Page指令声明中,可以看到Visual Studio 2012自动在Default.aspx页面中添加了Theme属性,代码如下:
示例8-3:在主题中应用CSS文件
源码路径:光盘\源文件\Chapter8\示例8-3\在主题中应用CSS文件\Default.aspx
运行结果如图8.7所示。
图8.7 运行结果图
在该示例中,在主题中添加CSS文件,在Web页面中应用主题。运行时,就可以看到样式表自动应用到了页面中。
注意:向页面中应用样式表时,ASP.NET需要在页面的<head>标签中添加runat="server"。Visual Studio 2012在生成页面时会自动在<head>标签中添加该代码。
8.3.3 在主题中应用图片
知识点讲解:光盘\视频讲解\第8章\在主题中应用图片.wmv
主题中除了包含皮肤、CSS文件外,还包含图片等其他资源。通常情况下,主题的资源文件与该主题的皮肤文件位于同一个文件夹中。但是资源文件也可以位于其他位置,只要在引用时,使用标准的链接路径即可。
【示例8-4】下面演示在主题中应用图片的方式。
(1)创建一个网站,命名为“在主题中应用CSS文件”。
(2)在解决方案资源管理器中的网站上单击右键,在弹出的快捷菜单中选择“添加ASP.NET文件夹”|“主题”命令。Visual Studio 2012会添加一个名为App_Themes的文件夹,并在该文件夹下添加一个命名为“主题1”的子文件夹。将“主题1”文件夹重命名为MyTheme。
(3)在MyTheme文件夹上单击鼠标右键,在弹出的快捷菜单中选择“添加”|“新建文件夹”命令。将该文件夹命名为Images,在Images下添加一幅图片1.jpg,如图8.8所示。
图8.8 解决方案资源管理器
(4)在MyTheme文件夹下添加一个皮肤文件SkinFile.skin。在SkinFile.skin文件中添加代码,具体如下:
示例8-4:在主题中应用图片
源码路径:光盘\源文件\Chapter8\示例8-4\在主题中应用图片\App_Themes\MyTheme\SkinFile.skin
(5)在网站中添加一个Web页面,命名为Default.aspx。在该页面中添加一个Image控件,代码如下:
示例8-4:在主题中应用图片
源码路径:光盘\源文件\Chapter8\示例8-4\在主题中应用图片\Default.aspx
运行结果如图8.9所示。
图8.9 运行结果图
在该示例中,在主题中添加图片,在Web页面中应用主题。运行时,就可以看到图片被加载到Web页面中。
注意:在主题中添加对图片的引用时,图片的地址是相对于主题文件夹的(即取图片的相对路径)。因此,主题应用到控件时,会自动在地址前面加上主题名称的路径。
8.4 主题冲突问题
知识点讲解:光盘\视频讲解\第8章\主题冲突问题.wmv
应用主题之后,主题和页面的控件设置会合并在一起,构成控件的最终设置。如果同时在控件和主题中定义了控件设置,则主题中的控件设置会覆盖页面控件的设置。但有时我们需要使用控件应用本身的属性,使得控件属性不被主题的属性设置覆盖。解决这种冲突有两种方式:将控件的EnableTheming属性设置为False;在页面的@Page指令中使用StyleSheetTheme属性代替Theme属性。本节我们就来处理这种冲突。
1. 将控件的EnableTheming属性设置为False
EnableTheming属性可以启用或者禁用主题。将控件的EnableTheming属性设置为False后,页面中设置该属性的控件将不去应用主题中的属性。
【示例8-5】在示例8-2的基础上,将Default.aspx页面的ListBox控件中EnableTheming属性的值设置为False。具体代码如下:
示例8-5:解决主题冲突问题
源码路径:光盘\源文件\Chapter8\示例8-5\处理主题冲突\Default.aspx
运行结果如图8.10所示。在该示例中,将ListBox控件的EnableTheming属性设置为False后,页面中设置该属性的控件将不去应用主题中的属性。
图8.10 运行结果图
2. 在页面的@Page指令中使用StyleSheetTheme属性代替Theme属性
StyleSheetTheme又称为样式表属性。当使用样式表属性时,开发人员可以在页面中设置控件特定的属性。这些属性比主题中的属性具有更高的优先级。
【示例8-6】在示例8-2的基础上,重新添加一个Web页面Default2.aspx,应用MyTheme主题。在Default2.aspx页面的@Page指令中使用StyleSheetTheme属性代替Theme属性。具体代码如下:
示例8-6:解决主题冲突问题
源码路径:光盘\源文件\Chapter8\示例8-5\处理主题冲突\Default2.aspx
运行结果如图8.11所示。
图8.11 运行结果图
在该示例中,将Web页面的Theme属性使用StyleSheetTheme属性替换后,就可以更改ListBox控件的属性。我们可以看到,页面中设置该属性的控件将不去应用主题中的属性。
8.5 在Web.config文件中配置主题
知识点讲解:光盘\视频讲解\第8章\在Web.config文件中配置主题.wmv
使用主题可以控制页面中HTML元素和ASP.NET控件的呈现,为不同控件的不同属性设置皮肤。除了在单个Web页面中应用主题外,还可以为整个网站应用主题。该功能是通过Web.config配置文件中的<pages>元素来指定Theme的。具体的配置代码如下所示:
Web.config文件的<pages>元素除了使用theme外,还可以使用styleSheetTheme来指定主题。代码如下:
在Web.config配置文件中指定了主题后,指定的主题将应用到整个网站。如果需要为特定的页面应用特殊的主题,可以在Web页面上指定Theme或者StyleSheetTheme属性。页面中的设置将会覆盖配置文件的设置。
8.6 动态加载主题
知识点讲解:光盘\视频讲解\第8章\动态加载主题.wmv
ASP.NET除了在页面声明或者配置文件中指定主题和外观首选项之外,还可以通过编程方式动态加载主题。只需要在PreInit事件中动态地指定Theme属性或者StyleSheetTheme属性,就可以实现主题的动态切换效果。
【示例8-7】下面演示动态加载主题的方式。
(1)创建一个网站,命名为“动态加载主题”。
(2)在解决方案资源管理器中的网站上单击右键,在弹出的快捷菜单中选择“添加ASP.NET文件夹”|“主题”命令。Visual Studio 2012会添加一个名为App_Themes的文件夹,并在该文件夹下添加一个名为“主题1”的子文件夹。将“主题1”文件夹重命名为MyTheme。
(3)在MyTheme文件夹上单击鼠标右键,在弹出的快捷菜单中选择“添加新项”命令。在打开的“添加新项”对话框中选择“外观文件”选项,命名为SkinFile.skin。单击“添加”按钮后,Visual Studio 2012将自动进入皮肤文件窗口。SkinFile.skin文件的代码如下:
示例8-7:动态加载主题
源码路径:光盘\源文件\Chapter8\示例8-7\动态加载主题\App_Themes\MyTheme\SkinFile.skin
(4)在网站上添加一个名称为Default.aspx的Web页面,在该页面上添加一个ListBox控件、一个Button控件。代码如下:
示例8-7:动态加载主题
源码路径:光盘\源文件\Chapter8\示例8-7\动态加载主题\Default.aspx
然后在Web页面中添加事件。用Page_Load事件代码来加载可选择的主题,用按钮的单击事件将用户选择的主题保存到会话变量中,用Page_Load事件动态地应用主题。Default.aspx页面后置代码如下:
示例8-7:动态加载主题
源码路径:光盘\源文件\Chapter8\示例8-7\动态加载主题\Default.aspx.cs
运行结果如图8.12和图8.13所示。
图8.12 运行结果图(1) | 图8.13 运行结果图(2) |
在该示例中,如果没有设置主题,则Page.Theme为空,不应用主题。如果设置主题,将应用保存在Session中的主题。
注意:在按钮的单击事件中使用Transfer()方法刷新页面而没有使用页面回发。因为页面若再次回应PreInit事件,最有效率的方法是Server.Transfer()方法。
8.7 小结
本章主要介绍了ASP.NET的主题,包括主题简介、创建主题、在主题中应用皮肤、在主题中应用CSS文件、在主题中应用图片、主题冲突问题、在Web.config文件中配置主题和动态加载主题。重点是对创建主题的掌握,有兴趣的读者可以在自己的网站中应用主题。
8.8 本章习题
习题8-1 在Visual Studio 2012中新建一个网站,命名为chapter8_1。在该网站上添加一个Web页面,命名为Default.aspx。在该页面中添加一个DropDownList列表框控件。在网站中添加一个主题,命名为“主题1”。在该主题中添加一个外观文件,命名为SkinFile.skin。在SkinFile.skin文件中为DropDownList控件添加皮肤设置。运行结果如图8.14所示。
图8.14 运行结果图
【分析】本题目主要考查的是对创建主题的掌握情况。
【关键代码】SkinFile.skin文件代码如下:
<asp:DropDownList runat="server" ForeColor="green" BackColor="lightblue" />
注意:在Web页面的page指令中会为Theme属性指定值。
习题8-2 在Visual Studio 2012中新建一个网站,命名为chapter8_2。在该网站上添加一个Web页面,命名为Default.aspx。在该Web页面中添加一个DropDownList列表框控件。然后在该网站中添加一个主题,命名为“主题1”。在该主题中添加一个外观文件,命名为SkinFile.skin。在该皮肤文件中设置DropDownList控件的皮肤,并将该皮肤命名为skin。在Default.aspx页面中使用该皮肤,运行结果图如图8.15所示。
图8.15 运行结果图
【分析】本题目主要考查的是对在主题中应用命名皮肤的掌握情况。
【关键代码】SkinFile.skin文件代码如下:
<asp:DropDownList runat="server" ForeColor="red" BackColor="lightblue" SkinId="skin" />
注意:需要在Web页面上为DropDownList控件添加命名皮肤skin。
习题8-3 在Visual Studio 2012中新建一个网站,命名为chapter8_3。在该网站上添加一个Web页面,命名为Default.aspx。在该页面中添加文本“今天你微笑了吗?”。在网站上添加一个主题,命名为“主题1”。在该主题中添加一个样式表文件,命名为StyleSheet.css。然后为Default.aspx页面应用主题,运行结果如图8.16所示。
图8.16 运行结果图
【分析】本题目主要考查的是对在主题中应用CSS文件的掌握情况。
【关键代码】StyleSheet.css文件代码如下:
body { font-family: 楷体; font-size: x-large; color: gray; background-color: #00FF99; }
注意:在Web页面中应用主题,即可应用主题下的样式表文件。
习题8-4 在Visual Studio 2012中新建一个网站,命名为chapter8_4。在该网站上添加一个Web页面,命名为Default.aspx。在该网站中添加一个主题,名称为“主题1”。在该主题中添加一个文件夹,命名为Images。在该文件夹中添加图片资源。在该主题中再添加一个外观文件,命名为SkinFile.skin。在SkinFile.skin文件中使用Images文件夹中的图片。在该网站上添加一个Web页面,运行结果如图8.17所示。
图8.17 运行结果图
【分析】本题目主要考查的是对在主题中应用图片的掌握情况。
【关键代码】SkinFile.skin文件代码如下:
<asp:Image runat="server" ImageUrl="Images/11.jpg" SkinID="Images" />
注意:在Web页面中应用主题中的图片,为图片的SkinId属性赋值。
习题8-5 在Visual Studio 2012中新建一个网站,命名为chapter8_5。在该网站上添加一个主题,命名为“主题1”。在该主题中添加一个外观文件,命名为SkinFile.skin。在该网站上添加一个Web页面,命名为Default.aspx。在该Web页面中添加一个ListBox控件、一个DropDownList控件和一个Button控件。在ListBox中选择主题,单击“应用主题”按钮,运行结果如图8.18所示。
图8.18 运行结果图
【分析】本题目主要考查的是对动态加载主题的掌握情况。
【关键代码】Default.aspx.cs文件代码如下:
using System.IO; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DirectoryInfo dir = new DirectoryInfo(Server.MapPath("App_Themes")); ListBox1.DataTextField = "name"; ListBox1.DataSource = dir.GetDirectories(); ListBox1.DataBind(); } } protected void Button1_Click(object sender, EventArgs e) { Session["Theme"] = ListBox1.SelectedValue; Server.Transfer(Request.FilePath); } protected void Page_PreInit(object sender, EventArgs e) { if (Session["Theme"] == null) { Page.Theme = ""; } else { Page.Theme = (string)Session["Theme"]; } } }
SkinFile.skin文件代码如下:
<asp:DropDownList runat="server" ForeColor="green" BackColor="lightblue" />