母版页和站点导航 (C#)

作者 :Scott Mitchell

下载 PDF

用户友好网站的一个共同特征是,它们具有一致的网站范围页面布局和导航方案。 本教程介绍如何在所有可轻松更新的页面中创建一致的外观。

简介

用户友好网站的一个共同特征是,它们具有一致的网站范围页面布局和导航方案。 ASP.NET 2.0 引入了两项新功能,可大大简化网站范围页面布局和导航方案的实现:母版页和网站导航。 母版页允许开发人员创建具有指定可编辑区域的网站范围模板。 然后,可以将此模板应用于网站中的 ASP.NET 页面。 此类 ASP.NET 页只需要为母版页的指定可编辑区域提供内容,母版页中的所有其他标记在使用母版页的所有 ASP.NET 页中都是相同的。 此模型允许开发人员定义和集中网站范围的页面布局,从而更轻松地在所有可以轻松更新的页面中创建一致的外观。

网站导航系统为页面开发人员提供了一种机制来定义站点地图,并为要以编程方式查询的站点地图提供了 API。 新的导航 Web 控件 Menu、TreeView 和 SiteMapPath 使在通用导航用户界面元素中呈现全部或部分网站地图变得容易。 我们将使用默认的网站导航提供程序,这意味着我们的站点地图将在 XML 格式的文件中定义。

为了说明这些概念并使教程网站更易于使用,让我们在本课程中定义网站范围的页面布局、实现网站地图以及添加导航 UI。 在本教程结束时,我们将拥有用于生成教程网页的完善网站设计。

本教程的最终结果

图 1:本教程的最终结果 (单击以查看全尺寸图像)

步骤 1:创建母版页

第一步是创建网站的母版页。 现在,我们的网站仅包含文件夹 () Northwind.xsd中的App_Code类型化数据集、) 文件夹中的 BLL 类 (CategoriesBLL.csProductsBLL.cs、 等、App_Code文件夹) 、数据库 (NORTHWND.MDF、文件夹) 、App_Data配置文件 (Web.config) ,以及 CSS 样式表文件 (Styles.css) 。 我清除了前两个教程中演示使用 DAL 和 BLL 的页面和文件,因为我们将在未来的教程中更详细地重新浏览这些示例。

项目中的文件

图 2:项目中的文件

若要创建母版页,请右键单击解决方案资源管理器中的项目名称,然后选择“添加新项”。 然后从模板列表中选择母版页类型并将其 Site.master命名为 。

向网站添加新母版页

图 3:向网站添加新母版页 (单击以查看全尺寸图像)

在母版页中定义网站范围的页面布局。 可以使用“设计”视图并添加所需的任何布局或 Web 控件,也可以在“源”视图中手动添加标记。 在母版页中,我使用 级联样式表 进行定位,并使用外部文件 Style.css中定义的 CSS 设置来设置样式。 虽然无法从下面所示的标记中辨别,但 CSS 规则的定义 <div>是,导航的内容是绝对定位的,以便它显示在左侧,并且具有 200 像素的固定宽度。

Site.master

<%@ Master Language="C#" AutoEventWireup="true"
    CodeFile="Site.master.cs" 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>Working with Data Tutorials</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div id="wrapper">

        <form id="form1" runat="server">

            <div id="header">
                <span class="title">Working with Data Tutorials</span>
                <span class="breadcrumb">
                 TODO: Breadcrumb will go here...</span>
            </div>

            <div id="content">
                <asp:contentplaceholder id="MainContent"
                 runat="server">
                  <!-- Page-specific content will go here... -->
                </asp:contentplaceholder>
            </div>

            <div id="navigation">
                TODO: Menu will go here...
            </div>
        </form>
    </div>
</body>
</html>

母版页定义静态页面布局以及可由使用母版页的 ASP.NET 页面编辑的区域。 这些内容可编辑区域由 ContentPlaceHolder 控件指示,该控件可在内容 <div>中查看。 母版页具有单个 ContentPlaceHolder (MainContent) ,但母版页可能有多个 ContentPlaceHolder。

在上面输入标记后,切换到“设计”视图将显示母版页的布局。 使用此母版页的任何 ASP.NET 页面都将具有此统一布局,并且能够指定该区域的 MainContent 标记。

通过设计视图查看时母版页

图 4:通过设计视图查看时母版页 (单击以查看全尺寸图像)

步骤 2:向网站添加主页

定义母版页后,我们可以为网站添加 ASP.NET 页面。 让我们首先添加 Default.aspx,我们网站的主页。 右键单击解决方案资源管理器中的项目名称,然后选择“添加新项”。 从模板列表中选择“Web 窗体”选项,并将文件 Default.aspx命名为 。 此外,检查“选择母版页”复选框。

添加新的 Web 窗体,选中“选择母版页”复选框

图 5:添加新的 Web 窗体,选中“选择母版页”复选框 (单击以查看全尺寸图像)

单击“确定”按钮后,系统会要求我们选择此新 ASP.NET 页应使用的母版页。 虽然项目中可以有多个母版页,但我们只有一个。

选择此 ASP.NET 页应使用的母版页

图 6:选择此 ASP.NET 页应使用的母版页 (单击以查看全尺寸图像)

选取母版页后,新的 ASP.NET 页将包含以下标记:

Default.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
  Runat="Server">
</asp:Content>

在 指令中 @Page ,引用了 () MasterPageFile="~/Site.master" 使用的母版页文件,ASP.NET 页的标记包含母版页中定义的每个 ContentPlaceHolder 控件的 Content 控件,该控件 ContentPlaceHolderID 将 Content 控件映射到特定的 ContentPlaceHolder。 在 Content 控件中放置要显示在相应 ContentPlaceHolder 中的标记的位置。 将 @Page 指令的 Title 属性设置为 Home,并将一些欢迎内容添加到 Content 控件:

Default.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeFile="Default.aspx.cs" Inherits="_Default" Title="Home" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
    Runat="Server">
    <h1>Welcome to the Working with Data Tutorial Site</h1>

    <p>This site is being built as part of a set of tutorials that
illustrate some of the new data access and databinding features in
ASP.NET 2.0 and Visual Web Developer.</p>

    <p>Over time, it will include a host of samples that
demonstrate:</p>

    <ul>
        <li>Building a DAL (data access layer),</li>
        <li>Using strongly typed TableAdapters and DataTables</li>
        <li>Master-Detail reports</li>
        <li>Filtering</li>
        <li>Paging,</li>
        <li>Two-way databinding,</li>
        <li>Editing,</li>
        <li>Deleting,</li>
        <li>Inserting,</li>
        <li>Hierarchical data browsing,</li>
        <li>Hierarchical drill-down,</li>
        <li>Optimistic concurrency,</li>
        <li>And more!</li>
    </ul>
</asp:Content>

Title指令中的 @Page 属性允许我们从 ASP.NET 页设置页面的标题,即使 <title> 元素是在母版页中定义的。 还可以使用 Page.Title以编程方式设置游戏。 另请注意,母版页对样式表 ((如) ) Style.css 的引用会自动更新,以便这些样式表在任何 ASP.NET 页面中工作,而不管 ASP.NET 页相对于母版页的目录是什么。

切换到“设计”视图,我们可以看到页面在浏览器中的外观。 请注意,在 ASP.NET 页的“设计”视图中,只有内容可编辑区域可编辑母版页中定义的非 ContentPlaceHolder 标记灰显。

ASP.NET 页面的设计视图同时显示可编辑区域和不可编辑区域

图 7:ASP.NET 页面的设计视图显示可编辑区域和不可编辑区域 (单击以查看全尺寸图像)

Default.aspx浏览器访问页面时,ASP.NET 引擎会自动合并页面的母版页内容和 ASP。NET 的内容,并将合并的内容呈现到发送到请求浏览器的最终 HTML 中。 更新母版页的内容后,使用此母版页的所有 ASP.NET 页面将在下次请求时将其内容与新的母版页内容重新合并。 简言之,母版页模型允许 (母版页) 定义单个页面布局模板,其更改会立即反映在整个网站中。

向网站添加其他 ASP.NET 页面

让我们花点时间将其他 ASP.NET 页存根添加到最终将保存各种报告演示的网站。 总共将有超过 35 个演示,因此,与其创建所有存根页面,不如创建前几个。 由于还会有许多类别的演示,为了更好地管理演示,请为类别添加一个文件夹。 现在添加以下三个文件夹:

  • BasicReporting
  • Filtering
  • CustomFormatting

最后,添加新文件,如图 8 中的解决方案资源管理器所示。 添加每个文件时,请记住检查“选择母版页”复选框。

添加以下文件

图 8:添加以下文件

步骤 2:创建站点地图

管理由多个页面组成的网站的难题之一是为访问者提供了一种直接浏览网站的方式。 首先,必须定义网站的导航结构。 接下来,此结构必须转换为可导航的用户界面元素,例如菜单或痕迹导航。 最后,当新页面添加到网站并删除现有页面时,需要维护和更新整个过程。 在 ASP.NET 2.0 之前,开发人员需要自行创建网站的导航结构、对其进行维护,并将其转换为可导航的用户界面元素。 但是,借助 ASP.NET 2.0,开发人员可以利用非常灵活的内置网站导航系统。

ASP.NET 2.0 网站导航系统为开发人员提供了一种定义站点地图,然后通过编程 API 访问此信息的方法。 ASP.NET 附带站点地图提供程序,该提供程序要求以特定方式以 XML 文件格式存储站点地图数据。 但是,由于站点导航系统是基于 提供程序模型 构建的,因此可以对其进行扩展以支持序列化站点地图信息的替代方法。 Jeff Prosise 的文章《你一直在等待的 SQL 站点地图提供程序》介绍了如何创建将站点地图存储在SQL Server数据库中的站点地图提供程序;另一个选项是基于文件系统结构创建站点地图提供程序

但是,在本教程中,我们将使用 ASP.NET 2.0 附带的默认站点地图提供程序。 若要创建站点地图,只需右键单击解决方案资源管理器中的项目名称,选择“添加新项”,然后选择“站点地图”选项。 将名称保留为 Web.sitemap ,然后单击“添加”按钮。

向项目添加站点地图

图 9:向项目添加站点地图 (单击以查看全尺寸图像)

站点地图文件是一个 XML 文件。 请注意,Visual Studio 为站点地图结构提供 IntelliSense。 站点地图文件必须将 节点 <siteMap> 作为其根节点,该根节点必须恰好包含一个 <siteMapNode> 子元素。 然后,第一 <siteMapNode> 个元素可以包含任意数量的后代 <siteMapNode> 元素。

定义站点映射以模拟文件系统结构。 也就是说,为三个文件夹中的每个文件夹添加一个 <siteMapNode> 元素,并为这些文件夹中的每个 ASP.NET 页添加子 <siteMapNode> 元素,如下所示:

Web.sitemap

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode url="~/Default.aspx" title="Home" description="Home">
      <siteMapNode title="Basic Reporting"
        url="~/BasicReporting/Default.aspx"
        description="Basic Reporting Samples">
        <siteMapNode url="~/BasicReporting/SimpleDisplay.aspx"
         title="Simple Display"
         description="Displays the complete contents
          of a database table." />
        <siteMapNode url="~/BasicReporting/DeclarativeParams.aspx"
          title="Declarative Parameters"
          description="Displays a subset of the contents
            of a database table using parameters." />
        <siteMapNode url="~/BasicReporting/ProgrammaticParams.aspx"
         title="Setting Parameter Values"
         description="Shows how to set parameter values
          programmatically." />
      </siteMapNode>

      <siteMapNode title="Filtering Reports"
       url="~/Filtering/Default.aspx"
       description="Samples of Reports that Support Filtering">
        <siteMapNode url="~/Filtering/FilterByDropDownList.aspx"
          title="Filter by Drop-Down List"
          description="Filter results using a drop-down list." />
        <siteMapNode url="~/Filtering/MasterDetailsDetails.aspx"
         title="Master-Details-Details"
         description="Filter results two levels down." />
        <siteMapNode url="~/Filtering/DetailsBySelecting.aspx"
          title="Details of Selected Row"
          description="Show detail results for a selected item in a GridView." />
      </siteMapNode>

      <siteMapNode title="Customized Formatting"
         url="~/CustomFormatting/Default.aspx"
         description="Samples of Reports Whose Formats are Customized">
        <siteMapNode url="~/CustomFormatting/CustomColors.aspx"
         title="Format Colors"
         description="Format the grid s colors based
           on the underlying data." />
        <siteMapNode
          url="~/CustomFormatting/GridViewTemplateField.aspx"
          title="Custom Content in a GridView"
          description="Shows using the TemplateField to
          customize the contents of a field in a GridView." />
        <siteMapNode
          url="~/CustomFormatting/DetailsViewTemplateField.aspx"
          title="Custom Content in a DetailsView"
          description="Shows using the TemplateField to customize
           the contents of a field in a DetailsView." />
        <siteMapNode url="~/CustomFormatting/FormView.aspx"
          title="Custom Content in a FormView"
          description="Illustrates using a FormView for a
           highly customized view." />
        <siteMapNode url="~/CustomFormatting/SummaryDataInFooter.aspx"
          title="Summary Data in Footer"
          description="Display summary data in the grids footer." />
      </siteMapNode>

  </siteMapNode>

</siteMap>

网站地图定义网站的导航结构,该结构是描述网站各个部分的层次结构。 中的每个<siteMapNode>Web.sitemap元素都表示网站导航结构中的一个部分。

站点地图表示分层导航结构

图 10:站点地图表示分层导航结构 (单击以查看全尺寸图像)

ASP.NET 通过.NET Framework的 SiteMap 类公开站点地图的结构。 此类具有 一个 CurrentNode 属性,该属性返回有关用户当前正在访问的部分的信息; RootNode 该属性返回站点地图) 中网站地图 (主页的根目录。 CurrentNodeRootNode 属性都返回 SiteMapNode 实例,这些实例具有 、、NextSiblingPreviousSibling、 等属性ParentNodeChildNodes,允许访问站点地图层次结构。

步骤 3:显示基于站点地图的菜单

可以通过编程方式(如在 ASP.NET 1.x 中)或通过新的 数据源控件以声明方式访问 ASP.NET 2.0 中的数据。 有几个内置数据源控件,例如用于访问关系数据库数据的 SqlDataSource 控件、用于访问类中的数据的 ObjectDataSource 控件等。 甚至可以创建自己的 自定义数据源控件

数据源控件充当 ASP.NET 页与基础数据之间的代理。 为了显示数据源控件的检索数据,我们通常会将另一个 Web 控件添加到页面,并将其绑定到数据源控件。 若要将 Web 控件绑定到数据源控件,只需将 Web 控件的 DataSourceID 属性设置为数据源控件属性 ID 的值。

为了帮助处理站点地图的数据,ASP.NET 包括 SiteMapDataSource 控件,该控件允许我们将 Web 控件绑定到网站地图。 树视图和菜单这两个 Web 控件通常用于提供导航用户界面。 若要将站点地图数据绑定到这两个控件之一,只需将 SiteMapDataSource 与相应设置其属性的 DataSourceID TreeView 或 Menu 控件一起添加到页面。 例如,我们可以使用以下标记将 Menu 控件添加到母版页:

<div id="navigation">
    <asp:Menu ID="Menu1" runat="server"
      DataSourceID="SiteMapDataSource1">
    </asp:Menu>

    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
</div>

为了更精细地控制发出的 HTML,我们可以将 SiteMapDataSource 控件绑定到 Repeater 控件,如下所示:

<div id="navigation">
    <ul>
        <li><asp:HyperLink runat="server" ID="lnkHome"
         NavigateUrl="~/Default.aspx">Home</asp:HyperLink></li>

        <asp:Repeater runat="server" ID="menu"
          DataSourceID="SiteMapDataSource1">
            <ItemTemplate>
                <li>
                    <asp:HyperLink runat="server"
                    NavigateUrl='<%# Eval("Url") %>'>
                    <%# Eval("Title") %></asp:HyperLink>
                </li>
            </ItemTemplate>
        </asp:Repeater>
    </ul>

    <asp:SiteMapDataSource ID="SiteMapDataSource1"
      runat="server" ShowStartingNode="false" />
</div>

SiteMapDataSource 控件一次返回站点地图层次结构一个级别,从站点地图) (主页的根站点地图节点开始,下一个级别 (基本报告、筛选报表和自定义格式设置) 等。 将 SiteMapDataSource 绑定到 Repeater 时,它会枚举返回的第一个级别,并实例化 ItemTemplate 第一个级别中的每个 SiteMapNode 实例。 若要访问 的特定属性,SiteMapNode可以使用 Eval(propertyName),这是获取 HyperLink 控件的每个 SiteMapNodeUrlTitle 属性的方式。

上述中继器示例将呈现以下标记:

<li>
    <a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
</li>

<li>
    <a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
</li>

<li>
    <a href="/Code/CustomFormatting/Default.aspx">
     Customized Formatting</a>
</li>

这些网站地图节点 (基本报告、筛选报表和自定义格式设置) 构成要呈现的站点地图 的第二 级,而不是第一级。 这是因为 SiteMapDataSource 的 ShowStartingNode 属性设置为 False,导致 SiteMapDataSource 绕过根站点地图节点,而是从返回站点地图层次结构中的第二个级别开始。

若要显示“基本报告”、“筛选报表”和“自定义格式”的子级SiteMapNode,可以将另一个中继器添加到初始中继器。ItemTemplate 第二个中继器将绑定到 SiteMapNode 实例的 ChildNodes 属性,如下所示:

<asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
    <ItemTemplate>
        <li>
            <asp:HyperLink runat="server"
             NavigateUrl='<%# Eval("Url") %>'>
             <%# Eval("Title") %></asp:HyperLink>

            <asp:Repeater runat="server"
                DataSource='<%# ((SiteMapNode) Container.DataItem).ChildNodes %>'>
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>

                <ItemTemplate>
                    <li>
                        <asp:HyperLink runat="server"
                         NavigateUrl='<%# Eval("Url") %>'>
                         <%# Eval("Title") %></asp:HyperLink>
                    </li>
                </ItemTemplate>

                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>
</asp:Repeater>

这两个中继器导致以下标记, (为简洁起见,删除了一些标记) :

<li>
    <a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
    <ul>
       <li>
          <a href="/Code/BasicReporting/SimpleDisplay.aspx">
            Simple Display</a>
       </li>
       <li>
          <a href="/Code/BasicReporting/DeclarativeParams.aspx">
            Declarative Parameters</a>
       </li>
       <li>
          <a href="/Code/BasicReporting/ProgrammaticParams.aspx">
            Setting Parameter Values</a>
       </li>
    </ul>
</li>

<li>
    <a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
    ...
</li>

<li>
    <a href="/Code/CustomFormatting/Default.aspx">
      Customized Formatting</a>
    ...
</li>

使用从 Rachel Andrew 的《 CSS 选集:101 基本提示、技巧 & 黑客》一书中选择的 CSS 样式, <ul> 将 和 <li> 元素设置样式,以便标记生成以下视觉输出:

由两个中继器和一些 CSS 组成的菜单

图 11:由两个中继器和一些 CSS 组成的菜单

此菜单位于母版页中,并绑定到 中 Web.sitemap定义的站点地图,这意味着对站点地图的任何更改都将立即反映在使用该 Site.master 母版页的所有页面上。

禁用 ViewState

所有 ASP.NET 控件都可以选择将其状态保存到 视图状态,视图状态在呈现的 HTML 中序列化为隐藏的窗体字段。 视图状态由控件用来记住它们在回发中以编程方式更改的状态,例如绑定到数据 Web 控件的数据。 虽然视图状态允许跨回发记住信息,但它会增加必须发送到客户端的标记的大小,如果不密切监视,可能会导致严重页面膨胀。 数据 Web 控件(尤其是 GridView)在向页面添加数十 KB 的额外标记方面尤其臭名昭著。 虽然这种增加对于宽带或 Intranet 用户来说可以忽略不计,但对于拨号用户的往返行程,视图状态可能会增加几秒钟。

若要查看视图状态的影响,请在浏览器中访问页面,然后在 Internet Explorer 中查看网页 (发送的源,转到“视图”菜单,然后选择“源”选项) 。 还可以打开 页面跟踪 ,以查看页面上每个控件使用的视图状态分配。 视图状态信息在名为 __VIEWSTATE的隐藏窗体字段中序列化,该字段位于紧邻开始<form>标记后的元素中<div>。 仅当正在使用 Web 窗体时,视图状态才会保留;如果 ASP.NET 页在其声明性语法中不包含 , <form runat="server"> 则呈现的标记中不会 __VIEWSTATE 有隐藏的窗体字段。

__VIEWSTATE母版页生成的表单字段向页面生成的标记添加大约 1,800 个字节。 此额外膨胀主要是由于 Repeater 控件,因为 SiteMapDataSource 控件的内容会保留为查看状态。 虽然额外的 1,800 个字节似乎不太令人兴奋,但使用包含许多字段和记录的 GridView 时,视图状态很容易膨胀 10 倍或更多。

通过将 属性设置为 EnableViewStatefalse,可以在页面或控件级别禁用视图状态,从而减少呈现的标记的大小。 由于数据 Web 控件的视图状态会跨回发保留绑定到数据 Web 控件的数据,因此在禁用数据 Web 控件的视图状态时,必须在每次回发时绑定数据。 在 ASP.NET 版本 1.x 中,此责任落在页面开发人员的肩上;但是,使用 ASP.NET 2.0 时,数据 Web 控件会在每次回发时重新绑定到其数据源控件(如果需要)。

为了减少页面的视图状态,请将 Repeater 控件的 EnableViewState 属性设置为 false。 这可以通过Designer中的属性窗口或以声明方式在源视图中完成。 进行此更改后,Repeater 的声明性标记应如下所示:

<asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1"
    EnableViewState="False">
    <ItemTemplate>
        ... <i>ItemTemplate contents omitted for brevity</i> ...
    </ItemTemplate>
</asp:Repeater>

进行此更改后,页面呈现的视图状态大小已缩小到仅 52 字节,视图状态大小节省 97%! 在本系列的教程中,我们将默认禁用数据 Web 控件的视图状态,以减小呈现的标记的大小。 在大多数示例中,EnableViewState属性将设置为 false ,并在不提及的情况下执行此操作。 讨论视图状态的唯一时间是在必须启用它才能使数据 Web 控件提供其预期功能的情况下。

步骤 4:添加痕迹导航

为了完成母版页,我们向每个页面添加痕迹导航 UI 元素。 痕迹导航可快速向用户显示其在站点层次结构中的当前位置。 在 ASP.NET 2.0 中添加痕迹导航很容易,只需将 SiteMapPath 控件添加到页面即可;无需代码。

对于站点,请将此控件添加到标头 <div>

<span class="breadcrumb">
    <asp:SiteMapPath ID="SiteMapPath1" runat="server">
    </asp:SiteMapPath>
</span>

痕迹导航显示用户在站点地图层次结构中访问的当前页,以及站点地图节点的“上级”,一直显示在站点地图) 的根 (主页。

痕迹导航在站点地图层次结构中显示当前页及其上级

图 12:痕迹导航在站点地图层次结构中显示当前页及其上级

步骤 5:为每个分区添加默认页面

我们网站中的教程分为不同的类别基本报告、筛选、自定义格式等,每个类别都有一个文件夹,相应的教程作为该文件夹中 ASP.NET 页。 此外,每个文件夹都包含一个 Default.aspx 页面。 对于此默认页面,我们来显示当前部分的所有教程。 也就是说,对于 Default.aspxBasicReporting 文件夹中的 ,我们将有指向 SimpleDisplay.aspxDeclarativeParams.aspxProgrammaticParams.aspx的链接。 在这里,我们同样可以使用 SiteMap 类和数据 Web 控件来根据 中 Web.sitemap定义的站点地图来显示此信息。

让我们再次使用中继器显示无序列表,但这次我们将显示教程的标题和说明。 由于需要为每个 Default.aspx 页面重复完成此操作的标记和代码,因此我们可以将此 UI 逻辑封装在 用户控件中。 在网站中创建名为 UserControls 的文件夹,并将名为 SectionLevelTutorialListing.ascx的 Web User Control 类型的新项添加到该文件夹,并添加以下标记:

将新的 Web 用户控件添加到 UserControls 文件夹

图 13:将新的 Web 用户控件添加到 UserControls 文件夹 (单击以查看全尺寸图像)

SectionLevelTutorialListing.ascx

<%@ Control Language="CS" AutoEventWireup="true"
    CodeFile="SectionLevelTutorialListing.ascx.cs"
    Inherits="UserControls_SectionLevelTutorialListing" %>
<asp:Repeater ID="TutorialList" runat="server" EnableViewState="False">
    <HeaderTemplate><ul></HeaderTemplate>
    <ItemTemplate>
        <li><asp:HyperLink runat="server"
         NavigateUrl='<%# Eval("Url") %>'
         Text='<%# Eval("Title") %>'></asp:HyperLink>
                - <%# Eval("Description") %></li>
    </ItemTemplate>
    <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

SectionLevelTutorialListing.ascx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class UserControls_SectionLevelTutorialListing : UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // If SiteMap.CurrentNode is not null,
        // bind CurrentNode ChildNodes to the GridView
        if (SiteMap.CurrentNode != null)
        {
            TutorialList.DataSource = SiteMap.CurrentNode.ChildNodes;
            TutorialList.DataBind();
        }
    }
}

在前面的 Repeater 示例中,我们以声明方式将数据绑定到 SiteMap Repeater; SectionLevelTutorialListing 但是,用户控件以编程方式执行此操作。 在事件处理程序中Page_Load,进行检查以确保此页面的 URL 映射到站点地图中的节点。 如果此用户控件用于没有相应 <siteMapNode> 条目的页面, SiteMap.CurrentNode 将返回 null 并且不会将任何数据绑定到中继器。 假设我们有 一个 CurrentNode,则将其 ChildNodes 集合绑定到 Repeater。 由于站点地图的设置 Default.aspx 使每个部分中的页面都是该部分中所有教程的父节点,因此此代码将显示指向该部分的所有教程的链接和说明,如下面的屏幕截图所示。

创建此中继器后,打开Default.aspx每个文件夹中的页面,转到“设计”视图,只需将“用户控件”从解决方案资源管理器拖到“设计”图面上,即可显示教程列表。

用户控件已添加到 Default.aspx

图 14:已将 Default.aspx 用户控件添加到 (单击以查看全尺寸图像)

列出了基本报告教程

图 15:列出基本报告教程 (单击以查看全尺寸图像)

总结

定义站点地图并完成母版页后,我们现在为数据相关教程提供了一致的页面布局和导航方案。 无论我们向网站添加多少页,更新网站范围的页面布局或网站导航信息都是一个快速而简单的过程,因为此信息是集中的。 具体而言,页面布局信息在母版页 Site.master 中定义,在 中的站点地图中 Web.sitemap定义。 我们不需要编写 任何 代码来实现此网站范围的页面布局和导航机制,我们在 Visual Studio 中保留完整的 WYSIWYG 设计器支持。

完成数据访问层和业务逻辑层并定义了一致的页面布局和站点导航后,我们就可以开始探索常见的报告模式了。 在接下来的三个教程中,我们将介绍显示 GridView、DetailsView 和 FormView 控件中从 BLL 检索到的数据的基本报告任务。

编程快乐!

深入阅读

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

关于作者

斯科特·米切尔是七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自 1998 年以来一直在使用 Microsoft Web 技术。 Scott 担任独立顾问、培训师和作家。 他的最新一本书是 山姆斯在 24 小时内 ASP.NET 2.0。 可以在 上mitchell@4GuysFromRolla.com联系他,也可以通过他的博客(可在 中找到http://ScottOnWriting.NET)。

特别感谢

本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是 Liz Shulok、Dennis Patterson 和 Hilton Giesenow。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处mitchell@4GuysFromRolla.com放置一行。