第10章 母版页及其主题
本章视频教学录像:25 分钟
为了达到一致的感觉,每个网站都需要统一的风格和布局。为了满足这个需求,我们曾经大量使用过框架和用户控件,但 ASP 2.0 为我们提供了一个新的功能——母版页。利用它可以创建页面布局(母版页),从而对网站中选定页或所有页(内容页)使用该页面布局。母版页的功能极大地简化了为站点创建一致外观的工作。
本章要点(已掌握的在方框中打钩)
□ 母版页的创建
□ 使用母版页创建内容页
□ 访问母版页中的控件
□ 主题概述
□ 创建并应用主题
□ 动态切换主题
10.1 母版页
本节视频教学录像:11分钟
从ASP.NET2.0开始提供了母版页功能。母版页由一个母版页和多个内容页构成,母版页的主要功能是为ASP.NET应用程序中的页面创建相同的布局和界面风格。
母版页的使用与普通页面类似,可以在其中放置文件或者图形、任何的HTML控件和Web控件、后置代码等。母版页的扩展名以.master结尾,不能被浏览器直接查看。母版页必须在被其他页面使用后才能进行显示。
母版页仅仅是一个页面模板,单独的母版页是不能被用户所访问的。单独的内容页也不能够使用。母版页和内容页有着严格的对应关系。母版页中包含多少个ContentPlaceHolder控件,那么内容页中也必须设置与其相对应的Content控件。当客户端浏览器向服务器发出请求,要求浏览某个内容页面时,引擎将同时执行内容页和母版页的代码,并将最终结果发送给客户端浏览器。
10.1.1 母版页的创建
母版页中包含的是多个页面的公共部分,因此,在创建母版页之前需要判断哪些是页面的公共部分,公共的部分由母版页负责创建。
创建母版页的具体步骤如下。
⑴新建ASP.NET空网站,在菜单栏中选择【网站】菜单,或在项目名称上点击右键,在弹出的快捷菜单栏中选择【添加新项】命令。
⑵打开【添加新项】对话框,如图所示。选择【母版页】,默认名为MasterPage.master。单击【添加】按钮就可以创建一个新的母版页。
添加母版页后,母版页默认会包含一个ContentPlaceHolder 控件。ContentPlaceHolder控件可以被认为是一个“内容占位符”,用来容纳内容页。在母版页中嵌入内容页后,就可以看出母版页的功能所在了。
10.1.2 使用母版页创建内容页
创建完母版页后,接下来就要创建内容页,内容页的创建与母版页的创建类似。下面通过一个简单的例子来介绍内容页的创建并嵌入母版页。
【范例10-1】创建一个母版页和一个内容页,并使内容页嵌入母版页中。
⑴新建ASP.NET空网站,参照上一节内容创建母版页并命名为MasterPage1。
⑵在ContentPlaceHolder控件下方加上一个超链接,链接到新浪网,源代码“<a href="Http://www.sina.com.cn" target=_blank>新浪< /a>”,如图所示。
⑶在项目名称上点击右键,点击【添加新项】,打开【添加新项】【Web窗体】,同时选中【选择母版页】复选框,单击【添加】按钮,弹出如图所示的“选择母版页”对话框。
⑷在该对话框中选择上步添加的母版页,单击【添加】按钮,就可以创建一个新的内容页。
我们会发现,内容页和母版页很相似,不同的是内容页上只有ContentPlaceHolder可以编辑,我们可以做任何想做的操作,而其他区域都不可以编辑。新浪超链接同样可以链接到新浪网。
提示
添加内容页也可以通过其他方法实现,在母版页上点击右键,选择“添加内容页”,也可以添加一个采用该母版页的内容页。
10.1.3 访问母版页的控件
很多情况下我们需要通过内容页去访问母版页中的对象。Page对象具有一个公共属性Master,该属性能够实现对相关母版页基类MasterPage的引用,母版页中的MasterPage相当于普通ASP.NET页面中的Page对象,因此,可以使用MasterPage对象实现对母版页中各个子对象的访问。我们借助MasterPage对象的FindControl方法实现。
【范例10-2】实现访问母版页中的控件。
⑴新建ASP.NET空网站,首先添加母版页,并将母版页命名为MasterPage2.Master;然后添加一个页面,使用刚才创建的母版页,采用默认名。
⑵分别在母版页和内容页上添加一个Label控件。母版页的Label控件的ID属性为LabMaster,用来显示系统日期;内容页的Label控件的ID属性为labContent,用来显示母版页中的Label控件值。
⑶在MasterPage2.Master母版页的Page_load事件中,使母版页的Label控件显示当前的系统时间,代码如下。
01 protected void Page_Load(object sender,EventArgs e)
02 {
03 this.labMaster.Text= "今天是 "+DateTime.Today.Year+ "年 "+DateTime.Today.Month+ "月 "+DateTime.Today.Day+ "日 ";
04 }
⑷在Default.aspx内容页中的Page_LoadComplete事件中,使内容页的Label控件显示母版页中的控件值的代码如下:
01 protected void page_LoadComplete(object sender,EventArgs e)
02 {
03 Label MLable1= (Label)this.Master.FindControl("labMaster");
04 this.labContent.Text=MLable1.Text;
05 }
【运行结果】
按【F5】键调试运行,或单击工具栏中的按钮,在弹出的对话框中选择【不进行调试直接运行】,单击【确定】按钮,即可在浏览器中显示如图所示的结果。
提示
读者需要注意的是,内容页Page_Load事件先于母版页的Page_Load事件引发。所以,这里我们使用Page_LoadComplete事件而不是Page_Load()事件。其中Page_LoadComplete事件是在生命周期内和网页加载结束时触发。
【范例分析】
DateTime.Today.Year是为了获取当前时间的年份数据,与DateTime.Now.Year.ToString()的作用相同;同样DateTime.Today.Month也可以用DateTime.Now.Month.ToString()代替。
10.2 主题
本节视频教学录像:10分钟
10.2.1 主题概述
主题由外观、级联样式表(CSS)、图像和其他资源构成。主题至少应该包括外观。
外观:外观文件是主题的核心内容,用于定义页面中服务器控件的外观。它包含各个控件的属性设置。控件外观设置类似于控件标记本身,但只包含要作为主题的一部分来设置的属性。如下代码就是定义了TextBox控件的外观代码。
<asp:TextBox runat ="server" BackColor ="PowderBlue" ForeColor ="RosyBrown"/>
级联样式表(CSS):主题还可以包含级联样式表(.css文件)。将.css文件放在主题目录中时,样式表自动作为主题的一部分应用,使用文件扩展名为.css的文件在主题文件夹中定义样式表。主题中可以包含一个或多个级联样式表。
图像和其他资源:主题还可以包含其他图形和其他资源,例如脚本文件或视频文件等。通常,主题的资源文件与该主题的外观文件位于同一个文件夹中,但也可以在Web应用程序的其他地方(不推荐)。
在Web应用程序中,主题文件需要存放在根目录的App_Themes文件夹下(全局主题除外),开发人员可手动或者使用Visual Studio 2010在网站的根目录以下创建该文件夹,如图所示。外观文件是主题的核心部分,每个文件夹下都可以包含一个或者多个外观文件。当主题较多,页面内容较复杂时,外观文件的组织就会出现问题。这就要求对主题文件进行有效的管理。通常根据SkinID,控件类型及文件3种方式进行组织。
10.2.2 创建并应用主题
创建主题时,需要创建外观文件,还可以为主题添加CSS样式。外观文件分为“默认外观”和“已命名外观”两种类型。我们可以通过不设置SkinID属性来实现,此时,向页面应用主题,默认外观自动应用于同一类型的所有控件。已命名外观是设置了SkinID属性的控件,不会自动按类型应用于控件,而是通过设置控件的SkinID将已命名外观应用于控件。控件外观的属性可以是简单属性,也可以是复杂属性。简单属性是控件外观设置中最常见的类型,例如背景颜色、空间的宽度等。复杂性主要包括集合属性、模板属性等。
主题中的样式主要用于设置页面和普通的HTML空间的外观样式。
简单的应用主题只需要在每个页面的头部标签<%@ Page%>中设置Theme属性为主题名即可,比较常用的是为单个页面和应用程序指定和禁用主题,为单个页面指定和禁用主题。
使用主题如下,需要注意的是如果页面单独使用stylesheettheme属性指定主题,那么内容页中定义的控件属性将覆盖stylesheettheme定义的控件属性。
<%@ Page Theme ="Theme"%>
或
<%@ Page Style SheetTheme ="ThemeName"%>
禁用单个页面主题如下:
<%@ Page EnableTheming ="false"%>
为应用程序指定和禁用主题时,可以在Web.Config文件中的<pages>配置内容,禁用时,只需要将<pages>配置节中的Theme属性或者StyleSheetTheme实行设置为空即可。
配置主题代码如下:
<configuration>
<system.web>
<pages theme ="ThemeName">< /pages>
< /system.web>
<connectionStrings/>
或
<configuration>
<system.web>
<pages StyleSheetTheme ="ThemeName">< /pages>
< /system.web>
<connectionStrings/>
【范例10-3】创建一个简单的主题并应用,外观如下图所示。
程序实现的主要步骤如下:
⑴新建空网站,在根目录下创建App_Themes文件夹用于存放主题。右键单击并选择“.NET文件夹”/“主题”命令,取名为TextBoxSkin.skin,在主题下新建外观文件,取名为TextBoxSkin.skin,用来设置TextBoxSkin.skin。源代码如下:
01 <asp:TextBox runat = "server" Text = "Hello World!" BackColor = "#FFE0C0" BorderColor ="#FFC080"
02 Font-Size= "12pt" ForeColor= "#C04000"Width= "149px"/>
03 <asp:TextBox SkinId= "textboxSkin" runat= "server" Text= "Hello World!"BackColor= "#FFFFC0"
04 BorderColor= "Olive"BorderStyle= "Dashed" Font-Size= "15px"Width= "224px"/>
⑵在主题下添加一个样式表文件,默认名为styleSheet.css,用来设置页面背景颜色、文本对齐方式及文本颜色。源代码如下:
01 body
02 {
03 text-align:center;
04 color:Yellow;
05 background-color:Green;
06 }
⑶在网页的默认页中,添加两个TextBox控件,应用创建的主题,需要在<%@ page%>标签中设置Theme属性来应用主题。源代码如下:
01 <% @ Page Language="C#"AutoEventWireup="true"
02 CodeFile="Default.aspx.cs" Inherits="_Default" Theme= "TextBoxSkin"%>
03 <!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN"
04 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
05 <html xmlns="http://www.w3.org/1999/xhtml">
06 <head runat= "server">
07 <title>创建并应用主题< /title>
08 < /head>
09 <body>
10 <form id= "form1" runat= "server">
11 <div>
12 <table>
13 <tr>
14 <td style= "width: 100px">
15 默认外观:< /td>
16 <td style= "width: 247px">
17 <asp:TextBox ID= "TextBox1" runat= "server">< /asp:TextBox>< /td>
18 < /tr>
19 <tr>
20 <td style= "width:100px">
21 命名外观:< /td>
22 <td style= "width:247px">
23 <asp:TextBox ID="TextBox2"runat="server"SkinID="textboxSkin">< /asp:TextBox>< /td>
24 < /tr>
25 < /table>
26 < /div>
27 < /form>
28 < /body>
29 < /html>
10.2.3 动态切换主题
除了在页面声明和配置文件中指定主题和外观首选项之外,还可以通过编程方式动态加载主题。
【范例10-4】动态加载主题界面如下图所示。
程序实现的主要步骤为:
⑴新建一个空网站,添加两个主题,分别命名为Theme1和Theme2,并且每个主题包含一个外观文件(TextBoxSkin.skin)和一个CSS文件(StyleSheet.css)用于设置页面的外观及控件外观。主题文件夹Theme1中的外观文件TextBoxSkin.skin的源代码如下:
01 <asp:TextBox runat="server" text="text1 text1" backcolor="#c0c0c0" bordercolor="#7f7f7f"
02 ForeColor="#004400" Font-Size="12pt" width="150pt"/>
03 <asp:TextBox SkinID="textBoxSkin" runat="server" text="text2 text2" BackColor="red"
04 BorderColor="green" ForeColor="yellow" Font-Size="15pt" width="150pt"/>
级联样式表文件StyleSheet.css的源代码如下:
01 body
02 {
03 text-align:center;
04 color:Yellow;
05 background-color:Navy;
06 }
07 A:link
08 {
09 color:White;
10 text-decoration:underline;
11 }
12 A:visited
13 {
14 color:White;
15 text-decoration:underline;
16 }
17 A:horver
18 {
19 color:Fuchsia;
20 text-decoration:underline;
21 font-style:italic;
22 }
23 input
24 {
25 border-color:Yellow;
26 }
主题文件夹Theme2中的外观文件TextBoxSkin.skin的源代码如下:
01<asp:TextBox runat="server" Text="skin2 test1"BackColor="#FFe0c0"BorderColor="#FFc080"
02 Font-Size="8pt" ForeColor="#C04000"width="150pt" />
03<asp:TextBox runat="server" SkinID="textBoxSkin" text="skin2 test2"BackColor="#ffffc0"
04 bordercolor="olive" font-size="10pt" borderstyle="dashed"width="150pt" />
级联样式表文件StyleSheet.css的源代码如下:
01 body
02 {
03 text-align:center;
04 color:#004000;
05 background-color:Aqua;
06 }
07 A:link
08 {
09 color:blue;
10 text-decoration:underline;
11 }
12 A:visited
13 {
14 color:blue;
15 text-decoration:underline;
16 }
17 A:horver
18 {
19 color:Silver;
20 text-decoration:underline;
21 font-style:italic;
22 }
23 input
24 {
25 border-color:#004040;
26 }
⑵在网站的默认主页 Default.aspx 中添加一个 DropDownList 控件、两个 TextBox 控件和一个HTML/Button控件。
DropDownList控件中包含两个选项,一个是”Theme1”,另外一个是”Theme2”。当用户选择任何一个选项时,都会触发DropDownList控件的SelectedIndexChanged事件,在该事件下,将选项的主题名存放在URL的QueryString(即theme)中,并重新加载页面。Default.aspx的代码如下:
01 <% @ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"%>
02 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
03 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
04 <html xmlns="http://www.w3.org/1999/xhtml">
05 <head id="Head1" runat="server">
06 <title>无标题< /title>
07 < /head>
08 <body>
09 <form id="form1" runat="server">
10 <div>
11 <h1>动态加载主题< /h1>
12 <span>选择主题< /span>
13 { <asp:DropDownList ID="dropdownlist1" runat="server"
14 onselectedindexchanged="dropdownlist1_SelectedIndexChanged" AutoPostBack="true">
15 <asp:ListItem Value="theme1">主题1< /asp:ListItem>
16 <asp:ListItem Value="theme2">主题2< /asp:ListItem>
17 < /asp:DropDownList>
18 <br />
19 <span>默认外观< /span>
20 <asp:TextBox ID="textBox1" runat="server">< /asp:TextBox>
21 <br />
22 <span>命名外观< /span>
23 <asp:TextBox ID="textBox2" runat="server">< /asp:TextBox>
24 <br />
25 <asp:Button ID="button1" runat="server" Text="kit it"/>
26 < /div>
27 < /form>
28 < /body>
29 < /html>
使用Theme属性指定页面的的主题,只能在页面的PreInit事件发生过程中或者提前设置,本事例在PreInit事件发生过程中修改Page对象Theme属性值。其代码如下:
01 public partial class _Default :System.Web.UI.Page
02 {
03 protected void Page_Load(object sender,EventArgs e)
04 {
05 }
06 protected void dropdownlist1_SelectedIndexChanged(object sender,EventArgs e)
07 {
08 string url=Request.Path+ "?theme="+dropdownlist1.SelectedItem.Value;
09 Response.Redirect(url);
10 }
11 void Page_PreInit(object sender,EventArgs e)
12 {
13 string theme= "theme1";
14 if (Request.QueryString["theme"]== null)
15 {
16 theme= "theme1";
17 }
18 else
19 {
20 theme=Request.QueryString["theme"];
21 }
22 Page.Theme= theme;
23 ListItem item=dropdownlist1.Items.FindByValue(theme);
24 if (item != null)
25 {
26 item.Selected= true;
27 }
28 }
29 }
10.3 高手点拨
本节视频教学录像:4分钟
1. 母版页怎么使用主题
母版页中不能直接使用主题,所以,要想在母版页中使用主题,需要在Web.config文件中的Pages节中进行配置,源代码如下:
01 <configuration>
02 <system.web>
03 <pages styleSheetTheme=”ThemeName”/>
04 < /system.web>
05 < /configuration>
2. Skin和CSS的区别
CSS 是用于控制所有 HTML 标记的外观。
Skin 是用于控制所有 ASP.NET 服务器调整的外观,并且可以通过属性 cssClass 定义它的 CSS 样式。
3. @Page中Theme与StylesheetTheme的区别
在应用主题文件时,有两种方法:在<%@Page Theme=""%>>中设置Theme和在<%@Page StylesheetTheme=""%>中设置StylesheetTheme。
两者的主要区别在于调用的优先级不同:
当设置Theme时,先调用页面中的属性,再调用theme中的属性,如果有重复的属性定义,最终以theme中的为准。
当设置StylesheetTheme时,先调用StylesheetTheme中定义的属性,再使用页面中定义的属性,如果有重复属性定义,最终结果以页面中定义的属性为准。
10.4 实战练习
1. 创建一个母版页和一个内容页,母版页中有一个TextBox控件,内容页需要嵌套在母版页下,实现在内容页中访问母版页中的TextBox控件。
2. 创建一个主题文件,内容需要包括外观和级联样式表,并应用于Default.aspx上。