SiteMapDataSource Web 服务器控件从站点地图提供程序中检索导航数据,然后将数据传递给可显示该数据的控件,如 TreeView 和 Menu 控件。
说明: SiteMap 控件也显示导航数据,但该控件不需要绑定到 SiteMapDataSource 控件。
SiteMapDataSource 控件包含来自站点地图的导航数据。此数据包括有关网站中的页的信息,如 URL、标题、说明和导航层次结构中的位置。若将导航数据存储在一个地方,则可以更方便地在网站的导航菜单中添加和删除项。
在 ASP 和 ASP.NET 的早期版本中,在向您的网站添加一个页然后在网站内的其他各页中添加指向该新页的链接时,必须手动添加链接,包括一个公共文件,或开发自定义导航功能。ASP.NET 2.0 版包含导航控件,这些控件使导航菜单的创建、自定义和维护变得更容易。
一、SiteMapDataSource 类
SiteMapDataSource 控件是站点地图数据的数据源,站点数据则由为站点配置的站点地图提供程序进行存储。SiteMapDataSource 使那些并非专门作为站点导航控件的 Web 服务器控件(如 TreeView、Menu 和 DropDownList 控件)能够绑定到分层的站点地图数据。可以使用这些 Web 服务器控件将站点地图显示一个为目录,或者对站点进行主动式导航。当然,您也可以使用 SiteMapPath 控件,该控件被专门设计为一个站点导航控件,因此不需要 SiteMapDataSource 控件的实例。
SiteMapDataSource 绑定到站点地图数据,并基于在站点地图层次结构中指定的起始节点显示其视图。默认情况下,起始节点是层次结构的根节点,但也可以是层次结构中的任何其他节点。起始节点由以下几个 SiteMapDataSource 属性的值来标识:
起始节点 | 属性值 |
层次结构的根节点(默认设置)。 | StartFromCurrentNode 为 false。 未设置 StartingNodeUrl。 |
表示当前正在查看的页的节点。 | StartFromCurrentNode 为 true。 未设置 StartingNodeUrl。 |
层次结构的特定节点。 | StartFromCurrentNode 为 false。 已设置 StartingNodeUrl。 |
如果 StartingNodeOffset 属性设置为非 0 的值,则它会影响起始节点以及由 SiteMapDataSource 控件基于该节点公开的站点地图数据层次结构。StartingNodeOffset 的值为一个负整数或正整数,该值标识从 StartFromCurrentNode 和 StartingNodeUrl 属性所标识的起始节点沿站点地图层次结构上移或下移的层级数,以便对数据源控件公开的子树的起始节点进行偏移。
如果 StartingNodeOffset 属性设置为负数 -n,则由数据源控件公开的子树的开始节点,是在层次结构中位于所标识开始节点之上 n 个级别的祖先节点。如果在层次结构树中,位于所标识开始节点之上的祖先节点的级别数小于值 n,子树的开始节点就是站点地图层次结构中的根节点。
如果 StartingNodeOffset 属性设置为正数 +n,则所公开子树的开始节点是位于所标识开始节点之下 n 个级别的子节点。由于层次结构中可能存在多个子节点的分支,因此,如果可能,SiteMapDataSource 会尝试根据所标识起始节点与表示当前被请求页的节点之间的路径,直接解析子节点。如果表示当前被请求页的节点不在所标识起始节点的子树中,则忽略 StartingNodeOffset 属性的值。如果表示当前被请求的页的节点与位于其上方的所标识开始节点之间的层级差距小于 n,则使用当前被请求的页作为开始节点。
站点地图数据是从 SiteMapProvider 对象(如作为 ASP.NET 的默认站点地图提供程序的 XmlSiteMapProvider)中检索的。可指定为站点配置的任何提供程序向 SiteMapDataSource 提供站点地图数据,并且通过访问 SiteMap.Providers 集合可获得可用提供程序的列表。
与所有数据源控件一样,SiteMapDataSource 的每个实例都与单个帮助器对象关联,该帮助器对象称为数据源视图。SiteMapDataSourceView 是一个基于站点地图数据的视图,根据数据源的属性进行设置,并且通过调用 GetHierarchicalView 方法来检索此视图。SiteMapDataSourceView 维护控件所绑定到的 SiteMapNodeCollection 对象。
默认情况下,起始节点是层次结构的根节点,但是您可将起始节点设置为任何节点。起始节点可以是相对于站点地图中当前位置的一个节点,或者是相对于某个绝对位置的节点。通过设置 StartingNodeUrl 属性可指定起始节点。
SiteMapDataSource 专用于导航数据,并且不支持排序、筛选、分页或缓存之类的常规数据源操作,也不支持更新、插入或删除之类的数据记录操作。
示例
下面的代码示例演示如何以声明方式使用 SiteMapDataSource 控件将 TreeView 控件绑定到一个站点地图。该站点地图数据从根节点级别开始检索。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html >
<head runat="server">
<title>ASP.NET Example</title>
</head>
<body>
<form id="form1" runat="server">
<asp:SiteMapDataSource
id="SiteMapDataSource1"
runat="server" />
<asp:TreeView
id="TreeView1"
runat="server"
DataSourceID="SiteMapDataSource1">
</asp:TreeView>
</form>
</body>
</html>
二、SiteMapPath 类
SiteMapPath 控件是一种站点导航控件,反映 SiteMap 对象提供的数据。它提供了一种用于轻松定位站点的节省空间方式,用作当前显示页在站点中位置的引用点。此种类型的控件通常称为面包屑或眉毛,因为它显示了超链接页名称的分层路径,从而提供了从当前位置沿页层次结构向上的跳转。SiteMapDataSource。SiteMapPath 对于分层页结构较深的站点很有用,在此类站点中 TreeView 或 Menu 可能需要较多的页空间。
SiteMapPath 控件直接使用网站的站点地图数据。如果将其用在未在站点地图中表示的页面上,则其不会显示。
SiteMapPath 由节点组成。路径中的每个元素均称为节点,用 SiteMapNodeItem 对象表示。锚定路径并表示分层树的根的节点称为根节点。表示当前显示页的节点称为当前节点。当前节点与根节点之间的任何其他节点都为父节点。下表描述了三种不同的节点类型。
节点类型 | 说明 |
根节点 | 锚定节点分层组的节点。 |
父节点 | 有一个或多个子节点但不是当前节点的节点。 |
当前节点 | 表示当前显示页的节点。 |
SiteMapPath 显示的每个节点都是 HyperLink 或 Literal 控件,您可以将模板或样式应用到这两种控件。对节点应用模板和样式需遵循两个优先级规则:
·如果为节点定义了模板,它会重写为节点定义的样式。
·特定于节点类型的模板和样式会重写为所有节点定义的常规模板和样式。
NodeStyle 和 NodeTemplate 属性适用于所有节点,而不考虑节点类型。如果同时定义了这两个属性,将优先使用 NodeTemplate。
CurrentNodeTemplate 和 CurrentNodeStyle 属性适用于表示当前显示页的节点。如果除了 CurrentNodeTemplate 外,还定义了 NodeTemplate,则将忽略它。如果除了 CurrentNodeStyle 外,还定义了 NodeStyle,则它将与 CurrentNodeStyle 合并,从而创建合并样式。此合并样式使用 CurrentNodeStyle 的所有元素,以及 NodeStyle 中不与 CurrentNodeStyle 冲突的任何附加元素。
RootNodeTemplate 和 RootNodeStyle 属性适用于表示站点导航层次结构根的节点。如果除了 RootNodeTemplate 外,还定义了 NodeTemplate,则将忽略它。如果除了 RootNodeStyle 外,还定义了 NodeStyle,则它将与 RootNodeStyle 合并,从而创建合并样式。此合并样式使用 RootNodeStyle 的所有元素,以及 NodeStyle 中不与 CurrentNodeStyle 冲突的任何附加元素。最后,如果当前显示页是该站点的根页,将使用 RootNodeTemplate 和 RootNodeStyle,而不是 CurrentNodeTemplate 或 CurrentNodeStyle。
SiteMapPath 控件将由 SiteMapProvider 属性标识的站点地图提供程序用作站点导航信息的数据源。如果未指定提供程序,它将使用站点的默认提供程序,此提供程序由 SiteMap.Provider 属性标识。通常,这是 ASP.NET 默认站点地图提供程序(即 XmlSiteMapProvider)的一个实例。如果在站点内使用了 SiteMapPath 控件,但未配置站点地图提供程序,该控件将引发 HttpException 异常。
SiteMapPath 控件还提供多个您可以对其进行编程的事件。这使您可以在每次发生事件时都运行一个自定义例程。下表列出了 SiteMapPath 控件支持的事件。
事件 | 说明 |
SiteMapPath 控件先创建一个 SiteMapNodeItem,然后将其与 SiteMapNode 关联时发生。 | |
将 SiteMapNodeItem 绑定到 SiteMapNode 包含的站点地图数据时发生。 |
派生自 SiteMapPath 的类会重写 InitializeItem 方法,以自定义导航控件包含的 SiteMapNodeItem 控件。为了完全控制 SiteMapNodeItem 对象的创建方式以及将其添加到 SiteMapPath 的方式,派生类会重写 CreateControlHierarchy 方法。
示例
下面的代码示例在 Web 窗体页中以声明方式使用了 SiteMapPath 控件。此示例演示一些优先级规则,这些规则控制了将模板和样式应用到 SiteMapPath 节点的顺序。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html >
<head runat="server">
<title>ASP.NET Example</title>
</head>
<body>
<form id="form1" runat="server">
<!-- The following example demonstrates some of the orders
of precedence when applying styles and templates to
functional nodes of a SiteMapPath.
The NodeStyle and RootNodeStyle define the same attributes,
but are different and conflict with each other: the
RootNodeStyle supersedes NodeStyle, and is the style
rendered. Notice, however, that the underline style
defined by NodeStyle is still applied.
Both a CurrentNodeStyle and a CurrentNodeTemplate are
defined. A template supersedes a style for a node
type, so CurrentNodeTemplate is displayed and CurrentNodeStyle
is ignored. -->
<asp:SiteMapPath ID="SiteMapPath1" runat="server"
RenderCurrentNodeAsLink="true"
NodeStyle-Font-Names="Franklin Gothic Medium"
NodeStyle-Font-Underline="true"
NodeStyle-Font-Bold="true"
RootNodeStyle-Font-Names="Symbol"
RootNodeStyle-Font-Bold="false"
CurrentNodeStyle-Font-Names="Verdana"
CurrentNodeStyle-Font-Size="10pt"
CurrentNodeStyle-Font-Bold="true"
CurrentNodeStyle-ForeColor="red"
CurrentNodeStyle-Font-Underline="false">
<CURRENTNODETEMPLATE>
<asp:Image id="Image1" runat="server" ImageUrl="WebForm2.jpg" AlternateText="WebForm2"/>
</CURRENTNODETEMPLATE>
</asp:SiteMapPath>
</form>
</body>
</html>
上一个示例使用了默认的站点地图提供程序,以及具有如下结构的 Web.sitemap 文件。
<siteMap>
<siteMapNode title="WebForm1" description="WebForm1" url="WebForm1.aspx" >
<siteMapNode title="WebForm2" description="WebForm2" url="WebForm2.aspx"/>
</siteMapNode>
</siteMap>
下面的代码示例演示如何通过重写 InitializeItem 方法,扩展 SiteMapPath 控件并向其添加新功能。DropDownSiteMapPath 控件在当前节点后添加一个 DropDownList,使得定位到当前页的子节点页面变得容易。此示例演示如何在创建项后使用 SiteMapNodeItem 对象,包括检查它们的 SiteMapNodeItemType 及调用 OnItemCreated 方法。
using System;
using System.Collections;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
// The DropDownNavigationPath is a class that extends the SiteMapPath
// control and renders a DropDownList after the CurrentNode. The
// DropDownList displays a list of pages found further down the site map
// hierarchy from the current one. Selecting an item in the DropDownList
// redirects to that page.
//
// For simplicity, the DropDownNavigationPath assumes the
// RootToCurrent PathDirection, and does not apply styles
// or templates the current node.
//
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Minimal)]
public class DropDownNavigationPath : SiteMapPath {
// Override the InitializeItem method to add a PathSeparator
// and DropDownList to the current node.
protected override void InitializeItem(SiteMapNodeItem item) {
// The only node that must be handled is the CurrentNode.
if (item.ItemType == SiteMapNodeItemType.Current)
{