演练:在 Visual Web Developer 中创建和使用 ASP.NET 母版页
更新:2007 年 11 月
本演练阐释如何创建一个母版页和几个内容页。母版页使您可以创建一个页面布局(模板页),然后创建各个页面,这些页面包含的内容在运行时与母版页合并。有关母版页的更多信息,请参见 ASP.NET 母版页概述。
本演练阐释以下任务:
创建母版页。
创建一个 ASP.NET 页,此页包含要在母版页中显示的内容。
运行母版页以显示不同的内容。
在运行时选择母版页。
先决条件
若要完成本演练,您需要:
Visual Studio 或 Microsoft Visual Web Developer 速成版。
(可选)可以用作母版页上的徽标的 .jpg、.gif 或其他图形文件。建议徽标的宽度不大于 48 像素。不过,可以根据需要决定是否显示徽标,而且图形的确切大小在本演练中并不重要。
创建网站
如果已经在 Visual Web Developer 中创建了一个网站(例如,按照 演练:在 Visual Web Developer 中创建基本网页 中的步骤),则可以使用该网站并转到下一节创建母版页。否则,按照下面的步骤创建一个新的网站和网页。
创建文件系统网站
打开 Visual Web Developer。
在“文件”菜单上单击“新建网站”。
出现“新建网站”对话框。
在“Visual Studio 已安装的模板”之下单击“ASP.NET 网站”。
在“位置”框中输入要保存网站页面的文件夹的名称。
例如,键入文件夹名“C:\WebSites”。
在“语言”列表中,单击您想使用的编程语言。
单击“确定”。
Visual Web Developer 将创建该文件夹和名为 Default.aspx 的新页。
创建母版页
母版页是用于设置页面外观的模板。在本节中,将首先创建一个母版页。然后,使用表格来对母版页进行布局,此母版页具有一个菜单、一个徽标和一个页脚,这些内容将在站点的每个页面中出现。还将使用内容占位符,这是母版页中的一个区域,可以使用内容页中的信息来替换此区域。
创建母版页
在“解决方案资源管理器”中右击网站的名称,然后单击“添加新项”。
在“Visual Studio 已安装的模板”之下单击“母版页”。
在“名称”框中键入“Master1”。
选中“将代码放在单独的文件中”复选框。
说明: 本演练假设您为所有页面使用代码隐藏文件。如果您使用的是单一文件 ASP.NET 页,则本演练中演示的代码可以使用,但将显示在“源”视图中,而不是显示在单独的代码文件中。
在“语言”列表中,单击您想使用的编程语言,然后单击“添加”。
即会在“源”视图中打开新的母版页。
在页面的顶部是一个 @ Master 声明,而不是通常在 ASP.NET 页顶部看到的 @ Page 声明。页面的主体包含一个 ContentPlaceHolder 控件,这是母版页中的一个区域,其中的可替换内容将在运行时由内容页合并。在本演练的稍后部分将更多地使用内容占位符。
对母版页进行布局
母版页定义站点中页面的外观。它可以包含静态文本和控件的任何组合。母版页还可以包含一个或多个内容占位符,这些占位符指定显示页面时动态内容出现的位置。
在本演练中,将使用一个表格来帮助在页面中定位元素。首先创建一个布局表格来保存母版页元素。在本节的稍后部分中将定位已经在页面上的内容占位符控件。
创建母版页的布局表格
在“源”视图中选定 Master1.master 文件,将验证的目标架构设置为 Microsoft Internet Explorer 6.0。若要设置此值,可以使用工具栏中的下拉列表,或从“工具”菜单中选择“选项”,然后单击“验证”。
切换到“设计”视图。
从“属性”窗口顶部的下拉列表中选择“DOCUMENT”,然后将“BgColor”设置为特别的颜色,如蓝色。
选择什么颜色并不重要。在本演练的稍后部分,将创建没有颜色的第二个母版页,与在这里选择的颜色形成对比。
单击要放置布局表格的页面。
说明: 请勿将布局表格放在 ContentPlaceHolder 控件内。
在“表”菜单上单击“插入表”。
在“插入表”对话框中,创建一个带有三行和一列的表,然后单击“确定”。
将光标置于表的第二行中。
在“表”菜单的“修改”子菜单中,单击“拆分单元”。
在“拆分单元”对话框中,选择“拆分成列”[Split into columns],再单击“确定”。
进行以下设置:
在中间行中,单击最左侧的列,然后在“属性”窗口中将其“宽度”设置为 48。
单击首行,然后在“属性”窗口中将其“高度”设置为 48。
单击末行,然后在“属性”窗口中将其“高度”设置为 48。
说明: 可以通过拖动表单元格的边框或在“属性”窗口中选择单元格并设置值,设置宽度和高度。
选中表中的所有单元格,将“BgColor”设置为与背景不同的颜色。
布局完表格后,可以将内容添加到母版页,此内容将在所有页面上显示。可以将版权消息添加为页脚,然后添加一个菜单。如果有可用的徽标图形,也可以添加此徽标。
将静态内容添加到母版页
单击底部单元格,然后键入页脚文本,如“Copyright 2007 Contoso Inc.”。
在“工具箱”中,从“导航”控件组将 Menu 控件拖动到顶部单元格中。
按照以下步骤创建菜单:
将 Menu 控件的 Orientation 属性设置为 Horizontal。
单击 Menu 控件上的智能标记,然后在“菜单任务”对话框中单击“编辑菜单项”。
在“项”之下单击“添加根节点”图标两次,添加两个菜单项:
单击第一个节点,然后将 Text 设置为“主页”,将 href 设置为“Home.aspx”。
单击第二个节点,然后将 Text 设置为“关于”,将 href 设置为“About.aspx”。
单击“确定”关闭“菜单项编辑器”对话框。
如果有可用作徽标的图形文件,请按照以下步骤将其放置到母版页上:
现在可以定位内容占位符,以指定母版页在运行时显示内容的位置。
添加内容占位符
将 ContentPlaceHolder 控件拖动到右中单元格中。
控件的 ID 属性为 ContentPlaceholder1。您可以保留或更改此名称。如果更改此名称,请记下更改的名称,因为稍后需要知道此名称。
保存页。
创建母版页的内容
母版页提供内容的模板。通过创建与母版页关联的 ASP.NET 页来定义母版页的内容。内容页是 ASP.NET 页的专用形式,它仅包含要与母版页合并的内容。在内容页中,添加用户请求该页面时要显示的文本和控件。
在本演练中,将为母版页添加两个带有内容的页面。第一个是主页,第二个是“关于”页面。
创建主页
在“解决方案资源管理器”中右击网站的名称,然后单击“添加新项”。
在“Visual Studio 已安装的模板”下单击“Web 窗体”。
在“名称”框中键入“主页”。
在“语言”列表中,单击您想使用的编程语言。
选中“选择母版页”复选框,然后单击“添加”。
出现“选择母版页”对话框。
单击“Master1.master”,然后单击“确定”。
即会创建一个新的 .aspx 文件。该页面包含一个 @ Page 指令,此指令将当前页附加到带有 MasterPageFile 属性的选定母版页,如下面的代码示例所示。
[Visual Basic]
<%@ Page Language="VB" MasterPageFile="~/Master1.master" ... %>
[C#]
<%@ Page Language="C#" MasterPageFile="~/Master1.master" ... %>
该页还包含一个 Content 控件元素,下面将会使用此控件元素。
内容页不具有常见的组成 ASP.NET 页的元素,如 html、body 或 form 元素。相反,通过替换在母版页中创建的占位符区域,仅添加要在母版页上显示的内容。
将内容添加到主页
切换到“设计”视图。
母版页中的 ContentPlaceHolder 控件在新的内容页中显示为 Content 控件。将显示其余的母版页内容,以便您可以查看布局。但这些内容显示为浅灰色,因为您在编辑内容页时不能更改这些内容。
在“属性”窗口的下拉列表中单击“DOCUMENT”,然后将“标题”设置为“Contoso 主页”。
可以独立设置每个内容页的标题,以便内容与母版页合并时在浏览器中显示正确的标题。标题信息存储在内容页的 @ Page 指令中。
在与母版页上的 ContentPlaceHolder1 匹配的 Content 控件中,键入“欢迎光临 Contoso 网站”。
选择文本,然后通过从“工具箱”上的“块格式”下拉列表中选择“标题 1”,将文本的格式设置为标题。
按 Enter,在 Content 控件中创建一个新的空白行,然后键入“感谢您访问本站”。
在这里添加的文本并不重要,可以键入任何有助于将此页识别为主页的文本。
保存页。
可以用与创建主页相同的方法创建“关于”页面。
创建“关于”页面
使用与创建主页相同的步骤添加名为 About.aspx 的新内容页。
请确定将新页面附加到 Master1.master 页,正如对主页的操作一样。
将页面的标题更改为“Contoso‘关于’页面”。
在内容区域中,键入“关于 Contoso”,然后选择文本,并从“工具箱”上面的“块格式”下拉列表中选择“标题 1”,将文本的格式设置为“标题 1”。
按 Enter 以创建新行,然后键入“从 1982 年起,Contoso 一直提供优质的软件服务。”
保存页。
测试页面。
可以运行页以进行测试,正如运行任何 ASP.NET 页一样。
测试页面
切换到 Home.aspx 页,然后按 Ctrl+F5。
ASP.NET 将 Home.aspx 页的内容与 Master1.master 页的布局合并到单个页面,并在浏览器中显示产生的页面。请注意,此页的 URL 为 Home.aspx;浏览器中不存在对母版页的引用。
单击“关于”链接。
显示 About.aspx 页。它亦与 Master1.master 页合并。
引用母版页成员
内容页中的代码可以引用母版页上的成员,包括母版页上的任何公共属性或方法以及任何控件。在演练的此部分中,在母版页上创建一个属性,然后在内容页中使用此属性的值。前提是网站的公司名已作为属性存储在母版页中,且内容页中对公司名的任何引用都基于此母版页属性。
第一步是将属性添加到母版页。
将属性添加到母版页
切换到或打开 Master1.master 页。
在“解决方案资源管理器”中右击 Master1.master,然后单击“查看代码”打开代码编辑器。
说明: 默认情况下,Visual Web Developer 会创建使用代码隐藏模型的页。如果愿意,可以使用单一文件模型来创建代码。有关更多信息,请参见 ASP.NET 网页代码模型。
在类定义中键入以下代码。
Public Property CompanyName() As String Get Return CType(ViewState("companyName"), String) End Get Set(ByVal Value As String) ViewState("companyName") = Value End Set End Property
public String CompanyName { get { return (String) ViewState["companyName"]; } set { ViewState["companyName"] = value; } }
此代码为母版页创建名为 CompanyName 的属性。在视图状态中存储此值,以便此值在回发之间保持不变。
在类定义中(但并非在属性代码中)添加以下代码。
Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.Init Me.CompanyName = "Contoso" End Sub
void Page_Init(Object sender, EventArgs e) { this.CompanyName = "Contoso"; }
在本示例中,将 CompanyName 属性的值硬编码到页中。
现在可以修改内容页,以便使用母版页的 CompanyName 属性。
在内容页中引用 CompanyName 属性
切换到或打开 Home.aspx 页。
切换到“源”视图。
在页面顶部的 @ Page 指令下,添加下面的 @ MasterType 指令:
<%@ MasterType virtualpath="~/Master1.master" %>
此指令将内容页的 Master 属性(即将使用此属性)绑定到 Master1.master 页。
切换到“设计”视图。
在 Content 控件中,将文本更改为“欢迎光临网站”。
在“工具箱”中,从“标准”组将 Label 控件拖动到 Content 控件上,并将其放置到静态文本的后面,使文本如下所示:
欢迎光临网站 [Label]
在“解决方案资源管理器”中右击“Home.aspx”,然后单击“查看代码”打开代码编辑器。
在类定义中添加下面的代码。
Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.Load CompanyName.Text = Master.CompanyName End Sub
void Page_Load(Object sender, EventArgs e) { CompanyName.Text = Master.CompanyName; }
内容页的 Master 属性返回对母版页的引用,该母版页在步骤 3 中添加的 @ MasterType 指令中定义。
现在可以测试内容页,以便确定它是否正确引用母版页的 CompanyName 属性。
测试对母版页属性的引用
切换到或打开 Home.aspx 页,然后按 Ctrl+F5 运行页面。
页面即会在浏览器中显示,其中文本为“欢迎光临网站 Contoso”。
关闭浏览器。
切换到或打开 Master1.master 代码隐藏页。
更改 Page_Init 处理程序,为属性赋一个不同的公司名,如下面的代码示例所示。
Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.Init Me.CompanyName = "New Company Name" End Sub
void Page_Init(Object sender, EventArgs e) { this.CompanyName = "New Company Name"; }
切换到 Home.aspx 页,然后按 Ctrl+F5 以再次运行页面。
这次,更新的公司名显示在页面中。
动态更改母版页
在某些情况下,可能希望能够动态更改母版页;也就是使用代码设置内容页的母版页。例如,可能希望允许用户从几个布局中进行选择,根据个人喜好设置母版页。
在演练的此部分中,将会把第二个母版页添加到网站,然后创建按钮使用户能够在两个母版页之间切换。因为两个母版页将会非常相似,所以制作第一个母版页的一个副本,对其进行修改,以用作第二个母版页。
制作一个母版页的副本
在“解决方案资源管理器”中右击 Master1.master,然后单击“复制”。
右击网站的名称,然后单击“粘贴”。
即会将一个母版页添加到网站,名为“复件 master1.master”。
右击“复件 master1.master”,单击“重命名”,然后将新母版页命名为“Master2.master”。
打开 Master2.master,然后在 @ Master 指令中将 Master1 更改为 Master2。
完成的页面指令类似于下面的代码示例:
<%@ Master Language="VB" CodeFile="Master2.master.vb" Inherits="Master2" %>
<%@ Master Language="C#" CodeFile="Master2.master.cs" Inherits="Master2" %>
切换到“设计”视图。
在“属性”窗口顶部的下拉列表中单击“DOCUMENT”。
清除 BgColor 属性。
新的母版页的外观和功能与 Master1.master 类似,但没有背景色。
打开 Master2.master 的代码文件,将母版页的代码隐藏文件中的类名从 Master1 更改为 Master2,以便与页的 Inherits 指令中的 @ Master 属性的值相匹配。
代码类似于下面的示例:
Partial Class Master2
public partial class Master2 : System.Web.UI.MasterPage
下一步是向每个母版页添加一个按钮,此按钮允许用户选择备用母版页。
添加用于选择备用母版页的按钮
切换到或打开 Master2.master 页。
在“工具箱”中,从“标准”节点,将 LinkButton 控件拖动到页面上,并将其放置在顶部表格单元格中的菜单之下。
将按钮的 Text 属性设置为“Colorful”。
双击此按钮,为其 Click 事件创建一个处理程序,然后添加以下突出显示的代码。
Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As EventArgs)_ Handles LinkButton1.Click Session("masterpage") = "Master1.master" Response.Redirect(Request.Url.ToString()) End Sub
[C#]
void LinkButton1_Click(Object sender, EventArgs e) { Session["masterpage"] = "Master1.master"; Response.Redirect(Request.Url.ToString()); }
此代码将备用母版页的文件名加载到一个持久的会话变量中,然后重新加载当前页。(Url 属性返回引用当前页的 Uri 对象。)很快将在使用母版页的名称的内容页中创建代码。
在“设计”视图中切换到或打开 Master1.master 页。
像在步骤 1 和 2 中一样添加一个 LinkButton 控件,并将其 Text 属性设置为“Plain”。
双击 Plain 按钮,为其 Click 事件创建一个处理程序,然后添加下面突出显示的代码。
Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As EventArgs)_ Handles LinkButton1.Click Session("masterpage") = "Master2.master" Response.Redirect(Request.Url.ToString()) End Sub
void LinkButton1_Click(Object sender, EventArgs e) { Session["masterpage"] = "Master2.master"; Response.Redirect(Request.Url.ToString()); }
此代码与 Master2.master 页中按钮的代码类似,不同之处在于它加载备用母版页。
现在在内容页中编写代码,此代码将动态加载用户选定的母版页。
编写代码以动态选择母版页
切换到或打开 About.aspx 页。
说明: 已经创建的主页包含一个 @ MasterType 指令,此指令实际上将此页绑定到单个母版页 (Master1.master)。因此,将无法动态地将母版页分配到主页,而是使用其他已创建的页。
在“解决方案资源管理器”中右击“About.aspx”,然后单击“查看代码”打开代码编辑器。
在类定义中添加下面的代码。
Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.PreInit If Not Session("masterpage") Is Nothing Then Me.MasterPageFile = CType(Session("masterpage"), String) End If End Sub
void Page_PreInit(Object sender, EventArgs e) { if(Session["masterpage"] != null) { this.MasterPageFile = (String) Session["masterpage"]; } }
此代码将当前页的 MasterPageFile 属性的值设置为会话变量中的值(如果有)。此代码必须在 Page_PreInit 处理程序中运行;它无法在任何晚于 Page_PreInit 处理程序发生的处理程序中运行(例如,在 Page_Init 处理程序中),因为必须建立母版页,使得页面可以创建其实例,然后可以进一步初始化。
现在可以测试动态母版页。
测试动态母版页
在 About.aspx 页中按 Ctrl+F5 运行此页面。
此页即会在浏览器中显示,它与其默认母版页 Master1.master 合并。
单击“Plain”链接。
即会重新显示此页,这一次它与没有背景色的 Master2.master 合并。
单击“Colorful”链接。
再次使用 Master1.master 显示该页。
使用母版页的注意事项
使用母版页时还应注意其他几个问题:
在实际的应用中,可能将公司名等信息存储在配置文件中,并直接在内容页读取此信息。不过,在这里讲述的情形提供有关如何在内容页引用母版页成员的简单阐释。
即使没有包括 @ MasterType 指令,也可以访问母版页上的成员。但是,若要执行此操作,必须将 Page.Master 属性强制转换为适当的母版页类型(如果页面没有母版页,则 Master 属性为 null)。有关更多信息,请参见 以编程方式使用 ASP.NET 母版页。
可以使用 Master.FindControls 方法引用母版页上的控件。有关更多信息,请参见 以编程方式使用 ASP.NET 母版页。
使用动态母版页时还应注意其他几个问题:
为了使本演练专注于母版页,本节中更改母版页的情形已经简化。在实际应用中,很可能显示备选的一些布局,然后使用配置文件存储用户的首选项。有关详细信息,请参见ASP.NET 配置文件属性概述。
可以配置网站,使所有页面使用相同的母版页。可能会有几个页应使用备用母版页,可以用类似于本演练的此节中演示的方式在代码中进行配置。有关详细信息,请参见 ASP.NET 母版页概述 中的“设置母版页范围”。
需要将 Home.aspx 页中的代码添加到想要重写默认母版页的每个页面上。
后续步骤
本演练阐释了母版页的基本功能。您可能想要尝试母版页的其他功能。例如,您可能希望:
创建带有多个内容占位符的母版页。然后,可以使用显示的每个页面的内容来填充一个或多个占位符。
定义具有默认内容的内容占位符。如果 ASP.NET 页不提供占位符的内容,母版页将显示默认内容。
以编程方式从内容页访问母版页的成员。这使您能够动态地更改运行时母版页的外观。有关详细信息,请参见如何:引用 ASP.NET 母版页的内容。
对母版页使用设备筛选,为不同的设备创建不同的布局,如为浏览器创建一个布局,而为特定类型的电话创建另一个布局。有关详细信息,请参见 ASP.NET 设备筛选概述。
了解如何将母版页放置在母版页内,以便创建组件化页面。有关详细信息,请参见嵌套的 ASP.NET 母版页。