使用母版页创建站点范围内布局 (VB)

作者 :Scott Mitchell

下载 PDF

本教程将介绍母版页的基础知识。 即,什么是母版页、如何创建母版页、什么是内容占位符、如何创建使用母版页的 ASP.NET 页、修改母版页如何自动反映在其关联的内容页中,等等。

简介

设计良好的网站的一个属性是一致的网站范围页面布局。 以 www.asp.net 网站为例。 在撰写本文时,每个页面的顶部和底部都有相同的内容。 如图 1 所示,每个页面的最顶部显示一个灰色条形图,其中包含 Microsoft 社区列表。 下面是网站徽标、网站翻译到的语言列表以及核心部分:主页、入门、学习、下载等。 同样,页面底部包括有关 www.asp.net 广告的信息、版权声明和隐私声明的链接。

www.asp.net 网站在所有页面上采用一致的外观

图 01www.asp.net 网站在所有页面上采用一致的外观 (单击以查看全尺寸图像)

设计良好的网站的另一个属性是可以轻松更改网站的外观。 图 1 显示了截至 2008 年 3 月 的 www.asp.net 主页,但从现在到本教程的发布,外观可能已发生变化。 也许顶部的菜单项将展开,以包含 MVC 框架的新部分。 或者,将推出具有不同颜色、字体和布局的全新设计。 将此类更改应用于整个网站应该是一个快速而简单的过程,不需要修改构成网站的数千个网页。

通过使用母版页,可以在 ASP.NET 中创建网站范围的 页面模板。 简言之,母版页是一种特殊类型的 ASP.NET 页,用于定义所有 内容页 中通用的标记,以及在内容页的基础上可自定义的区域。 (内容页是绑定到母版页的 ASP.NET 页。) 每当母版页的布局或格式更改时,其所有内容页的输出同样会立即更新,这使得应用网站范围的外观更改与更新和部署单个文件 ((即母版页) )一样简单。

这是使用母版页探索的系列教程中的第一个教程。 在本系列教程中,我们:

  • 检查如何创建母版页及其关联的内容页,
  • 讨论各种提示、技巧和陷阱,
  • 确定常见的母版页缺陷并探索解决方法,
  • 了解如何从内容页访问母版页,反之亦然,
  • 了解如何在运行时指定内容页的母版页,以及
  • 其他高级母版页主题。

这些教程旨在简洁,并提供分步说明和大量屏幕截图,以直观地引导你完成该过程。 每个教程都以 C# 和 Visual Basic 版本提供,并包括所用完整代码的下载。

本首篇教程从母版页基础知识开始。 我们将讨论母版页的工作原理、使用 Visual Web Developer 创建母版页和关联的内容页,以及母版页的更改如何立即反映在其内容页中。 现在就开始吧!

了解母版页的工作原理

使用一致的网站范围页面布局构建网站要求每个网页除了发出自定义内容外,还发出通用格式标记。 例如,虽然 www.asp.net 上的每个教程或论坛文章都有其自己的唯一内容,但每个页面还呈现一系列显示顶级部分链接的常见 <div> 元素:主页、入门、Learn 等。

有多种技术可用于创建外观一致的网页。 一种朴素的方法是简单地将通用布局标记复制并粘贴到所有网页中,但这种方法有许多缺点。 对于初学者,每次创建新页面时,都必须记住将共享内容复制并粘贴到页面中。 这种复制和粘贴操作已经成熟,因此可能会出现错误,因为可能会意外地仅将共享标记的子集复制到新页面中。 最重要的是,此方法使将现有网站范围的外观替换为新的外观是一件非常痛苦的事情,因为网站中的每个页面都必须进行编辑才能使用新的外观和感觉。

在 ASP.NET 2.0 版之前,页面开发人员通常会在 用户控件 中放置通用标记,然后将这些用户控件添加到每个页面。 此方法要求页面开发人员记住手动将用户控件添加到每个新页面,但允许更轻松地在网站范围内进行修改,因为在更新通用标记时,只需要修改用户控件。 遗憾的是,Visual Studio .NET 2002 和 2003(用于创建 ASP.NET 1.x 应用程序的 Visual Studio 版本)在“设计”视图中呈现为灰色框。 因此,使用此方法的页面开发人员不喜欢 WYSIWYG 设计时环境。

ASP.NET 版本 2.0 和 Visual Studio 2005 中引入了 母版页,解决了使用用户控件的缺点。 母版页是一种特殊类型的 ASP.NET 页,用于定义网站范围的标记和关联的内容页定义其自定义标记的区域。 如步骤 1 中所示,这些区域由 ContentPlaceHolder 控件定义。 ContentPlaceHolder 控件仅表示母版页的控件层次结构中可由内容页注入自定义内容的位置。

注意

自 ASP.NET 2.0 版以来,母版页的核心概念和功能没有变化。 但是,Visual Studio 2008 为嵌套母版页提供设计时支持,这是 Visual Studio 2005 中缺少的功能。 我们将在后面的教程中介绍如何使用嵌套母版页。

图 2 显示了 www.asp.net 的母版页的外观。 请注意,母版页定义了通用的网站范围布局(每个页面的顶部、底部和右侧的标记),以及位于左中(每个网页的唯一内容所在的位置)的 ContentPlaceHolder。

母版页基于内容页定义 Site-Wide 布局和可编辑的区域

图 02:母版页基于内容页定义 Site-Wide 布局和可编辑区域

定义母版页后,可以通过复选框的刻度将其绑定到新的 ASP.NET 页。 这些 ASP.NET 页(称为内容页)包含母版页的每个 ContentPlaceHolder 控件的 Content 控件。 通过浏览器访问内容页时,ASP.NET 引擎会创建母版页的控件层次结构,并将内容页的控件层次结构注入到相应位置。 呈现此组合的控件层次结构,生成的 HTML 将返回到最终用户的浏览器。 因此,内容页发出在 ContentPlaceHolder 控件外部在其母版页中定义的通用标记,以及在其自己的 Content 控件中定义的特定于页面的标记。 图 3 说明了此概念。

请求页的标记融合到母版页中

图 03:请求页的标记融合到母版页 (单击以查看全尺寸图像)

现在我们已经讨论了母版页的工作原理,让我们看看使用 Visual Web Developer 创建母版页和关联的内容页。

注意

为了尽可能吸引最广泛的受众,我们将使用 ASP.NET 3.5 和 Microsoft 的免费版 Visual Studio 2008 Visual Web Developer 2008 创建我们在整个教程系列中构建的 ASP.NET 网站。 如果尚未升级到 ASP.NET 3.5,请不要担心 -这些教程中讨论的概念与 ASP.NET 2.0 和 Visual Studio 2005 同样适用于 。 但是,某些演示应用程序可能会使用.NET Framework版本 3.5 中的新增功能;使用 3.5 特定功能时,我包含一个说明,其中讨论了如何在版本 2.0 中实现类似的功能。 请记住,可从每个教程下载的演示应用程序面向.NET Framework版本 3.5,这会生成包含 Web.config 3.5 特定配置元素的文件。 长话短说,如果尚未在计算机上安装 .NET 3.5,则无需首先从 Web.config中删除 3.5 特定标记,可下载的 Web 应用程序将无法运行。 有关本主题的详细信息,请参阅 Web.config 文件

步骤 1:创建母版页

在探索创建和使用母版和内容页之前,我们首先需要一个 ASP.NET 网站。 首先创建一个新的基于文件系统 ASP.NET 网站。 若要完成此操作,请启动 Visual Web Developer,然后转到“文件”菜单并选择“新建网站”,显示“新建网站”对话框 (请参阅图 4) 。 选择“ASP.NET 网站”模板,将“位置”下拉列表设置为“文件系统”,选择要放置网站的文件夹,并将语言设置为“Visual Basic”。 这将创建一个包含 Default.aspx ASP.NET 页、 App_Data 文件夹和 Web.config 文件的新网站。

注意

Visual Studio 支持两种项目管理模式:网站项目和 Web 应用程序项目。 网站项目缺少项目文件,而 Web 应用程序项目模拟 Visual Studio .NET 2002/2003 中的项目体系结构 - 它们包含一个项目文件,并将项目的源代码编译为单个程序集,该程序集位于 /bin 文件夹中。 Visual Studio 2005 最初仅支持网站项目,但 Web 应用程序项目模型已随 Service Pack 1 重新引入;Visual Studio 2008 提供这两种项目模型。 但是,Visual Web Developer 2005 和 2008 版本仅支持网站项目。 在本系列教程中,我使用网站项目模型进行演示。 如果你使用的是非 Express 版本,并且想要改用 Web 应用程序项目模型 ,请随意执行此操作,但请注意,你在屏幕上看到的内容与必须执行的步骤与这些教程中所示的屏幕截图和提供的说明之间可能存在一些差异。

System-Based 网站创建新文件

图 04:System-Based 网站创建新文件 (单击以查看全尺寸图像)

接下来,右键单击“项目名称”,选择“添加新项”,然后选择“母版页”模板,将母版页添加到根目录中的网站。 请注意,母版页以扩展名 .master结尾。 将此新母版页 Site.master 命名为 ,然后单击“添加”。

将名为 Site.master 的母版页添加到网站

图 05:将名为 的 Site.master 母版页添加到网站 (单击以查看全尺寸图像)

通过 Visual Web Developer 添加新母版页文件将使用以下声明性标记创建母版页:

<%@ Master Language="VB" CodeFile="Site.master.vb" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//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>Untitled Page</title>
 <asp:ContentPlaceHolder id="head" runat="server">
 </asp:ContentPlaceHolder>
</head>
<body>
 <form id="form1" runat="server">
 <div>
 <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
 
 </asp:ContentPlaceHolder>
 </div>
 </form>
</body>
</html>

声明性标记中的第一行是 @Master 指令。 指令@Master类似于 @Page ASP.NET 页中显示的 指令。 它定义服务器端语言 (VB) 以及有关母版页的代码隐藏类的位置和继承的信息。

DOCTYPE和 页面的声明性标记显示在 指令下方@Master。 该页包含静态 HTML 以及四个服务器端控件:

  • Web 窗体 (<form runat="server">) (因为所有 ASP.NET 页通常都有一个 Web 窗体),并且由于母版页可能包含必须出现在 Web 窗体中的 Web 控件,因此请确保将 Web 窗体添加到母版页 (,而不是将 Web 窗体添加到) 的每个内容页。
  • 名为 ContentPlaceHolder1的 ContentPlaceHolder 控件- 此 ContentPlaceHolder 控件显示在 Web 窗体中,并用作内容页用户界面的区域。
  • 服务器端 <head> 元素 - <head> 元素具有 runat="server" 属性,因此可通过服务器端代码对其进行访问。 以 <head> 这种方式实现 元素,以便以编程方式添加或调整页面的标题和其他 <head>相关标记。 例如,设置 ASP.NET 页的 Title 属性会 <title> 更改服务器控件呈现的 <head> 元素。
  • 名为 head的 ContentPlaceHolder 控件- 此 ContentPlaceHolder 控件显示在服务器控件中<head>,可用于以声明方式向 <head> 元素添加内容。

此默认母版页声明性标记用作设计自己的母版页的起点。 可以随意编辑 HTML 或将其他 Web 控件或 ContentPlaceHolders 添加到母版页。

注意

设计母版页时,请确保母版页包含 Web 窗体,并且此 Web 窗体中至少显示一个 ContentPlaceHolder 控件。

创建简单网站布局

让我们展开 Site.master的默认声明性标记,以创建所有页面共享的网站布局:一个通用标题;一个包含导航、新闻和其他网站范围内容的左列;以及一个显示“由 Microsoft ASP.NET 提供支持”图标的页脚。 图 6 显示了通过浏览器查看母版页的内容页之一时的最终结果。 图 6 中的红色圆圈区域特定于 (Default.aspx) 访问的页面;其他内容在母版页中定义,因此在所有内容页中都是一致的。

母版页定义顶部、左侧和底部部分的标记

图 06:母版页定义顶部、左侧和底部部分的标记 (单击以查看全尺寸图像)

若要实现图 6 中显示的网站布局,请首先更新 Site.master 母版页,使其包含以下声明性标记:

<%@ Master Language="VB" CodeFile="Site.master.vb" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//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>Untitled Page</title>
 <asp:ContentPlaceHolder id="head" runat="server">
 </asp:ContentPlaceHolder>
 <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
 <form id="form1" runat="server">
 <div id="topContent">
 <a href="Default.aspx">Master Pages Tutorials</a>
 </div>
 
 <div id="mainContent">
 <asp:ContentPlaceHolder id="MainContent" runat="server">
 </asp:ContentPlaceHolder>
 </div>
 
 <div id="leftContent">
 <h3>Lessons</h3>    
 <ul>
 <li>TODO</li>
 </ul>
 <h3>News</h3>    
 <ul>
 <li>TODO</li>
 </ul>
 </div>
 
 <div id="footerContent">
 <img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
 </div>
 </form>
  </body>
</html>

母版页的布局是使用一系列 <div> HTML 元素定义的。 topContent<div>包含显示在每页顶部的标记,而 mainContentleftContentfooterContent<div> 分别用于显示页面的内容、左列和“由 Microsoft ASP.NET 提供支持”图标。 除了添加这些 <div> 元素外,我还将 ID 主要 ContentPlaceHolder 控件的 属性从 ContentPlaceHolder1 重命名为 MainContent

这些各种 <div> 元素的格式和布局规则在 级联样式表 (CSS) 文件中 Styles.css拼写出来,该文件是通过 <link> 母版页元素 <head> 中的 元素指定的。 这些不同的规则定义上述每个 <div> 元素的外观。 例如, topContent<div> 显示“母版页教程”文本和链接的 元素在 中 Styles.css 指定了其格式规则,如下所示:

#topContent {
 text-align: right;
 background-color: #600;
 color: White;
 font-size: x-large;
 text-decoration: none;
 font-weight: bold;
 padding: 10px;
 height: 50px;
}

如果在计算机中继续操作,则需要下载本教程随附的代码, Styles.css 并将 文件添加到项目中。 同样,还需要创建一个名为 Images 的文件夹,并将下载的演示网站中的“由 Microsoft ASP.NET 提供支持”图标复制到项目。

注意

本文不讨论 CSS 和网页格式设置。 有关 CSS 的详细信息,检查 W3Schools.com 上的 CSS 教程。 我还建议下载本教程随附的代码,并使用 中的 Styles.css CSS 设置来查看不同格式规则的效果。

使用现有设计模板创建母版页

多年来,我为中小型企业构建了许多 ASP.NET Web 应用程序。 我的一些客户有他们想要使用的现有网站布局;其他人聘请了一位称职的图形设计师。 几个委托我设计网站布局。 如图 6 所示,让程序员设计网站的布局通常与让会计在医生纳税时进行开胸手术一样明智。

幸运的是,有无数的网站提供免费的 HTML 设计模板 - 谷歌返回了超过600万个搜索词“免费网站模板”的结果。我最喜欢的一个是 OpenDesigns.org。找到喜欢的网站模板后,将 CSS 文件和图像添加到网站项目,并将模板的 HTML 集成到母版页中。

注意

Microsoft 还提供了许多 免费 ASP.NET 设计入门工具包模板 ,这些模板集成到 Visual Studio 中的“新建网站”对话框中。

步骤 2:创建关联内容页

创建母版页后,我们便可以开始创建绑定到母版页 ASP.NET 页。 此类页面称为 内容页

让我们向项目添加新 ASP.NET 页,并将其绑定到 Site.master 母版页。 右键单击解决方案资源管理器中的项目名称,然后选择“添加新项”选项。 选择 Web 表单模板,输入名称 About.aspx,然后检查“选择母版页”复选框,如图 7 所示。 这样做将显示“选择母版页”对话框, (请参阅图 8) ,可从中选择要使用的母版页。

注意

如果使用 Web 应用程序项目模型而不是网站项目模型创建了 ASP.NET 网站,则不会在图 7 所示的“添加新项”对话框中看到“选择母版页”复选框。 若要在使用 Web 应用程序项目模型时创建内容页,必须选择 Web 内容表单模板而不是 Web 表单模板。 选择 Web 内容表单模板并单击“添加”后,将显示图 8 中显示的相同“选择母版页”对话框。

添加新内容页

图 07:添加新内容页 (单击以查看全尺寸图像)

选择 Site.master 母版页

图 08:选择 Site.master 母版页 (单击以查看全尺寸图像)

如以下声明性标记所示,新内容页包含指向 @Page 其母版页的指令,以及母版页的每个 ContentPlaceHolder 控件的 Content 控件。

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="About.aspx.vb" Inherits="About" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>

注意

在步骤 1 的“创建简单网站布局”部分中,我已 ContentPlaceHolder1 将 重命名为 MainContent。 如果不以相同的方式重命名此 ContentPlaceHolder 控件的 ID ,则内容页的声明性标记将与上面所示的标记略有不同。 也就是说,第二个 Content 控件的 ContentPlaceHolderID 将反映 ID 母版页中相应 ContentPlaceHolder 控件的 。

呈现内容页时,ASP.NET 引擎必须将页面的内容控件与其母版页的 ContentPlaceHolder 控件融合在一起。 ASP.NET 引擎根据 @Page 指令的 属性确定内容页的 MasterPageFile 母版页。 如上述标记所示,此内容页绑定到 ~/Site.master

因为母版页有两个 ContentPlaceHolder 控件 - headMainContent - Visual Web Developer 生成了两个 Content 控件。 每个 Content 控件通过其 ContentPlaceHolderID 属性引用特定的 ContentPlaceHolder。

母版页在以前的网站范围模板技术上大放异彩的是,其设计时支持。 图 9 显示了 About.aspx 通过 Visual Web 开发人员的设计视图查看时的内容页。 请注意,虽然母版页内容可见,但它是灰显的,无法修改。 但是,与母版页的 ContentPlaceHolders 对应的 Content 控件是可编辑的。 与任何其他 ASP.NET 页一样,可以通过“源”或“设计”视图添加 Web 控件来创建内容页的界面。

内容页的设计视图同时显示 Page-Specific 和母版页内容

图 09:内容页的设计视图同时显示 Page-Specific 和母版页内容 (单击以查看全尺寸图像)

将标记和 Web 控件添加到内容页

花点时间为 About.aspx 页面创建一些内容。 如图 10 所示,我输入了“关于作者”标题和几段文本,但也可以随意添加 Web 控件。 创建此界面后,通过浏览器访问 About.aspx 页面。

通过浏览器访问About.aspx页

图 10:通过浏览器访问 About.aspx 页面 (单击以查看全尺寸图像)

请务必了解,请求的内容页及其关联的母版页是融合在一起的,并完全在 Web 服务器上呈现。 然后,向最终用户的浏览器发送生成的融合 HTML。 若要验证这一点,请通过转到“视图”菜单并选择“源”来查看浏览器收到的 HTML。 请注意,没有框架或任何其他专用技术可用于在单个窗口中显示两个不同的网页。

将母版页绑定到现有 ASP.NET 页

正如我们在此步骤中看到的,将新内容页添加到 ASP.NET Web 应用程序就像选中“选择母版页”复选框并选择母版页一样简单。 遗憾的是,将现有 ASP.NET 页转换为母版页并不容易。

若要将母版页绑定到现有 ASP.NET 页,需要执行以下步骤:

  1. MasterPageFile 属性添加到 ASP.NET 页的 @Page 指令,并将其指向相应的母版页。
  2. 为母版页中的每个 ContentPlaceHolders 添加 Content 控件。
  3. 有选择地将 ASP.NET 页面的现有内容剪切并粘贴到相应的“内容”控件中。 我在这里说“选择性”,因为 ASP.NET 页可能包含已由母版页表示的标记,例如 DOCTYPE<html> 元素和 Web 窗体。

有关此过程的分步说明以及屏幕截图,检查 Scott Guthrie的使用母版页和网站导航教程。 “更新 Default.aspxDataSample.aspx 以使用母版页”部分详细介绍了这些步骤。

由于创建新内容页比将现有 ASP.NET 页转换为内容页要容易得多,因此建议每当创建新的 ASP.NET 网站时,向网站添加母版页。 将所有新 ASP.NET 页绑定到此母版页。 不必担心初始母版页是否非常简单或简单;稍后可以更新母版页。

注意

创建新的 ASP.NET 应用程序时,Visual Web Developer 会添加一个 Default.aspx 未绑定到母版页的页面。 如果要练习将现有 ASP.NET 页转换为内容页,请继续操作并使用 Default.aspx执行此操作。 或者,可以删除 Default.aspx 并重新添加它,但这次选中“选择母版页”复选框。

步骤 3:更新母版页的标记

母版页的主要优点之一是,单个母版页可用于定义网站上许多页面的整体布局。 因此,更新网站的外观需要更新单个文件 - 母版页。

为了说明此行为,让我们更新母版页,将当前日期包含在左侧列的顶部。 将名为 的 DateDisplay Label 添加到 leftContent<div>

<div id="leftContent">
 <p>
 <asp:Label ID="DateDisplay" runat="server"></asp:Label>
 </p>
 
 <h3>Lessons</h3>    
 <ul>
 <li>TODO</li>
 </ul>
 <h3>News</h3>    
 <ul>
 <li>TODO</li>
 </ul>
</div>

接下来,为母版页创建 Page_Load 事件处理程序并添加以下代码:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd")
End Sub

上面的代码将 Label 的 Text 属性设置为当前日期和时间,格式为星期、月份名称和两位数的日期 (见图 11) 。 进行此更改后,请重新访问其中一个内容页面。 如图 11 所示,生成的标记会立即更新,以包含对母版页的更改。

查看内容页时,母版页的更改会反映出来

图 11:查看内容页时反映母版页的更改 (单击以查看全尺寸图像)

注意

如本示例所示,母版页可能包含服务器端 Web 控件、代码和事件处理程序。

总结

母版页使 ASP.NET 开发人员能够设计易于更新的一致的网站范围布局。 创建母版页及其关联的内容页与创建标准 ASP.NET 页面一样简单,因为 Visual Web Developer 提供丰富的设计时支持。

在本教程中创建的母版页示例有两个 ContentPlaceHolder 控件:head 和 MainContent。 但是,我们只在内容页中为 MainContent ContentPlaceHolder 控件指定了标记。 在下一教程中,我们将介绍如何在内容页中使用多个内容控件。 我们还了解了如何在母版页中定义内容控件的默认标记,以及如何在使用母版页中定义的默认标记和从内容页提供自定义标记之间进行切换。

编程愉快!

深入阅读

有关本教程中讨论的主题的详细信息,请参阅以下资源:

关于作者

Scott Mitchell 是多本 ASP/ASP.NET 书籍的作者,4GuysFromRolla.com 的创始人,自 1998 年以来一直从事 Microsoft Web 技术工作。 Scott 担任独立顾问、培训师和作家。 他的最新书是 山姆自学 ASP.NET 在24小时内3.5。 可在 上或通过他的博客http://ScottOnWriting.NET联系 mitchell@4GuysFromRolla.com Scott。

特别感谢

有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处放置一行 mitchell@4GuysFromRolla.com