控件:计划进行到 Visual Studio 2005 导航控件的迁移

翻译|其它|编辑:郝浩|2006-04-18 16:36:00.000|阅读 1590 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


本文基于 ASP.NET 2.0 的 2004 年 4 月社区技术预览。本文包含的所有信息随时可能更改。.

本文讨论:

    •SiteMapDataSource 和 SiteMapPath 控件

    •TreeView 控件

    •ASP.NET 1.1 的 Breadcrumb 导航控件

本文使用了下列技术:

    ASP.NET 和 Visual Basic .NET

以下位置提供了代码下载:

NavigationControls.exe(145KB)

本页内容

在为 Web 应用程序生成 UI 时,首要工作之一是设计 Web 站点的总体结构,包括所有站点导航。导航控件通常放在 Web 页的左侧或顶部,并且可能包括日益流行的 Breadcrumb 导航(它显示了用户必须预先经过的路径),从而创建总体菜单系统。要实现导航,可以使用多种技术,但对于开发人员而言它们通常过于繁琐。这方面的例子有 DHTML、include 文件(对于那些使用传统 ASP 的人们而言)和 ASP.NET 中的用户控件。有时导航元素被硬编码,但更常见的情形是导航项目被保存在数据存储中以供在运行时进行只读访问 — 无论是在数据库中(并且被缓存)还是在 XML 配置文件中。

在 ASP.NET 2.0 中,实现站点导航所需的大多数工作都被内置,以便您可以利用丰富的功能集,并且无须编写一行服务器端代码。

简单的 Web 站点

为了向您演示使用 ASP.NET 2.0 导航控件生成 Web 站点是如何简单,我们已经创建了一家虚构的万事通型计算机公司:Northwind Traders。该公司的 Web 站点在左侧有一个菜单,在右上侧有一个 Breadcrumb。请在 Visual Studio®2005 设计器中观察一个页面的设计(如图 1 所示),您可以看到有三个控件被圈了起来。用蓝色圈起来的是 SiteMapPath 控件,它有效地显示了常见的 Breadcrumb 导航。用红色圈起来的是 TreeView 控件,它当前被设置为显示平面视图,并且不能展开。用绿色圈起来的是 SiteMapDataSource 控件,它充当 TreeView 控件的数据源。在我们向您演练新的导航控件、它们的属性和其他重要项目时,请记住这一画面。


图 1 Visual Studio 2005 设计器中的页面

Web.SiteMap 文件

新增导航控件的关键之处在于新的 web.SiteMap 文件,如图 2 所示。这是一个标准 XML 文件,它充当导航项目的默认数据存储。在 Visual Studio 2005 中创建新的 Web 站点时,默认情况下不会添加 web.SiteMap 文件,因此您必须自己手动添加该文件(在最终版本问世之前,这很可能发生变化)。要添加该文件,请右键单击 Web 站点并选择 Add New Item。在 Standard Templates 下,选择 XML File 并将其重命名为 web.SiteMap(最终版本将支持把 SiteMap 文件添加为唯一的类型)。

创建了该文件之后,需要根据 web.SiteMap 的架构完成该文件(参见图 3),这不会有任何困难或麻烦。基本上,您需要一个根元素 (<siteMap>) 以及零个或更多个嵌套的<siteMapNode> 元素。注意,<siteMapNode> 元素的结构是逻辑性的,并不需要映射到 Web 站点的物理目录结构。例如,Northwind Traders Web 站点的文件全部位于根目录中。另一件需要记住的事情是对于每个 <siteMapNode>元素,URL 属性都必须在 SiteMap 文件中是唯一的。还要注意,在 Visual Studio 2005 的 2004 年 3 月 技术预览版中,在填写 web.SiteMap 文件时没有可用的 IntelliSense ®。

为使 web.SiteMap 文件可供导航控件使用,提供了一个默认的站点映射提供程序。在 machine.config 文件安装的 Visual Studio 2005 中,默认的站点映射提供程序名为 AspNetXmlSiteMapProvider,并且使用类类型 System.Web.XmlSiteMapProvider。该提供程序具有用于确定默认站点映射文件的属性。这一属性 SiteMapFile 的值为 "web.SiteMap"。一个名为 SiteMapProvider 的新的抽象基类(XmlSiteMapProvider 即派生于该类)已经被添加到下一版本的 Microsoft?.NET 框架中,使您可以实现自己的站点映射提供程序。

您应该注意,在 Visual Studio 2005 发布之前,web.SiteMap 文件的名称有可能更改。例如,为了遵循 .config 命名约定,该文件可能最终被命名为 SiteMap.config。

SiteMapPath 控件

在我们讨论该控件的细节之前,首先花一点儿时间了解一下 Web 站点中 Breadcrumb 踪迹的重要性。在中大型 Web 站点中,用户很容易即刻迷失在链接迷宫中,并且用户经常难以找到返回其踪迹起始位置的路线。这正是 Breadcrumb 对于用户体验如此重要的地方。Breadcrumb 导航使用户可以快速了解他们在站点中所处的位置,而不必返回主页并重新开始。

要在下一版本的 Visual Studio 中创建这一类型的导航,可以使用 SiteMapPath 控件。默认情况下,该控件使用 web.SiteMap 文件作为其数据存储,因此一旦您创建并填写了该文件,您就已经完成了在 Web 站点上实现 Breadcrumb 导航的一半工作。

SiteMapPath 控件位于设计器工具箱的 Navigation 选项卡的下方,您可以将其从设计器中拖放到 Web 窗体上。完成该工作之后,您将在您的 Web 站点中拥有基于 web.SiteMap 文件中元素的基本 Breadcrumb 踪迹。您将有可能希望调整 SiteMapPath 控件的属性以适应站点的总体设计。SiteMapPath 控件有太多的属性,无法在此全部深入进行讨论,但我们将介绍您应该立刻熟悉的几个属性。

PathDirection默认值为 RootToCurrent,它将以下面的方式显示 Breadcrumb:Home > Products > Software。另一个选项是 CurrentToRoot,它将前面的顺序颠倒过来:Software > Products > Home。

PathSeparator这是您希望在 Breadcrumb 的节点之间显示的任意文本。不要忘记包含前导和尾随空格。例如,要显示“Home > Products > Software”,您应该将该属性设置为 " > ",而不是 ">"。

RenderCurrentNodeAsLink它基本上确定了是否在 Breadcrumb 中将您正在访问的当前页显示为指向它本身的链接。默认值为 False。

该下一列表中的每个项目都是一组属性,用于定义所有字体和样式项目以及常规外观。每组属性都包含相同的属性子集。

CurrentNodeStyle赋予 Breadcrumb 中的当前节点其外观(重写 NodeStyle)。

HoverNodeStyle确定当您将鼠标悬停在 Breadcrumb 节点上方时该节点的外观。

NodeStyle在显示 Breadcrumb 时,赋予 Breadcrumb 中的所有节点一致的样式(除非该样式被 RootNodeStyle 或 CurrentNodeStyle 重写)。

PathSeparatorStyle设置您在 PathSeparator 中定义的任意文本的外观。

RootNodeStyle确定 Breadcrumb 的根节点的样式(重写 NodeStyle)。

正如您所看到的,您对于 Breadcrumb 的行为和外观具有完全的控制,而您无须编写一行服务器端代码就可以获得这一控制。例如,如果您希望用户快速识别 Web 站点的 Breadcrumb 中的当前节点,您可以将 CurrentNodeStyle 下的 font bold(粗体)属性设置为 True,或者将 font size(字号)设置为 Large,同时,可以将 NodeStyle 下的 font bold 属性设置为 False,而将其 font size 设置为 Small。快速查看一下 Northwind Traders Web 站点主页的源代码,可以明白我们是如何实现 SiteMapPath 控件的:

<asp:sitemappath id="SiteMapPath1" runat="server" pathseparator=" -> ">
        <hovernodestyle cssclass="crumbHoverNode" />
        <nodestyle cssclass="crumbNode" />
        <pathseparatorstyle cssclass="crumbPathSeparator" />
</asp:sitemappath>

SiteMapPath 控件也具有一个名为 SiteMapProvider 的属性。当保留为空(默认值)时,该控件将使用前面提到的 AspNetXmlSiteMapProvider(或 XmlSiteMapProvider),而后者将读取 web.SiteMap 文件。如果您创建了自己的站点映射提供程序,并且在 machine.config 或 web.config 中添加该项,则这就是您用来进行相应更改的属性。

SiteMapDataSource 控件

当您需要查看层次结构数据(如常见的导航结构)时,该控件非常重要。SiteMapDataSource 控件经常被用作供其他控件(如 TreeView 或 DropDownList 控件)绑定到的数据源。要使用 SiteMapDataSource 控件,请在设计器工具箱的 Data 选项卡下找到它,然后将其拖到您的 Web 窗体上。



图 4 SiteMapDataSource 属性

如果您观察一下图 4,您将看到 SiteMapDataSource 控件的属性列表不是很大,因此让我们了解一下其每个属性的细节。

EnableViewState如果您已在使用 ASP.NET,该属性将是非常熟悉的。它用于打开或关闭 ViewState。默认情况下,该值被设置为 True。

FlatDepth该属性指定从层次结构站点映射(由 SiteMapProvider 提供,它在默认情况下为 web.SiteMap 文件)中检索节点的深度。默认值为 -1,这表示对深度没有限制。值 0 对应于层次结构的根节点级别,而正整数对应于低于根节点的多个级别。如果您有一个较深的层次结构,并且希望将显示限制到固定的级别数,这将很有用。

ParentLevelsDisplayed指定要检索的父节点的级别数(相对于当前节点)。默认值为 -1,意味着对所检索的父级别没有限制。

SiteMapProvider确定供控件绑定到的站点映射提供程序。默认值为空,意味着控件使用前面讨论过的默认站点映射提供程序。如果您希望使用自己的站点映射提供程序,而不是使用默认的站点映射提供程序,则应该在此处键入该提供程序。

SiteMapViewType确定查看数据源的方式。默认值为 Tree,它使用与站点映射所指定的相同的层次结构来表示数据。其他值为 Flat 和 Path。Flat 仅显示节点的平面视图,不带层次结构,而 Path 将数据显示为当前节点和根节点之间的层次结构路径,与 SiteMapPath 控件呈现其站点映射数据所用的方法一样。

StartingDepth指定控件开始从 web.SiteMap 文件中检索 元素的深度。默认值为 -1,表示对于数据源开始检索节点的深度没有限制。值 0 表示根节点。

StartingNodeType默认情况下,该属性设置为 Root,这意味着起始节点为层次结构的根节点,但您可以将起始节点设置为任意节点。通过将该属性设置为 Parent 或 Current,可以将起始节点设置为相对于站点映射中当前位置的某个节点。如果您使用 Parent,则控件总是从当前显示页的父节点开始,除非当前显示页对应于根节点。如果该属性被设置为 Current,则控件总是从代表当前显示页的节点开始。

StartingNodeUrl如果不将起始节点设置为 Root、Current 或 Parent 节点,则可以将 web.SiteMap 文件中元素的 URL 指定为起始节点。设置该属性时,将优先于 StartingDepth 和 StartingNodeType 属性。

ID在使用控件作为其他控件(如 TreeView 或 DropDownList 控件)的数据源时,记下该控件的 ID。

下面表示了 Northwind Traders Web 站点上的一个典型的 SiteMapDataSource 控件声明,它对于所有属性都使用默认值(SiteMapViewType 除外):

<asp:sitemapdatasource id="SiteMapDataSource1" runat="server"
    sitemapviewtype="Flat" />

对于您可以拥有的 SiteMapDataSource 控件的数量,没有任何限制。例如,您可以在 Web 页的左侧拥有一个绑定到一个 SiteMapDataSource 控件的 TreeView 控件,而在右侧拥有绑定到另一个 SiteMapDataSource 控件的平面导航控件。

TreeView 控件

那些已经使用 Windows 窗体开发过基于 Windows? 的应用程序的读者十分熟悉 TreeView 控件;然而,在 Web 应用程序领域,使用 TreeView 还不太普遍。当前要在 Web 站点中实现与 TreeView 类似的功能,通常必须在客户端编写大量的 DHTML,以使其正常工作。这被证明是非常痛苦的,因为您必须考虑各种 Web 浏览器及其各个版本的所有特质,而测试将十分困难。在 ASP.NET 2.0 中,所有这些复杂性都不存在了,它们被封装在新增的 TreeView 控件中。

要想使用 TreeView 控件进行站点导航,最容易的方法是从设计器工具箱中拖动该控件(位于 Core 选项卡下),并且将其数据源绑定到 SiteMapDataSource 控件。在完成该工作以后,其余的实现涉及到设置属性,自始至终不必编写任何服务器端代码。就像 SiteMapPath 控件一样,在本文中难以对其所有属性进行讨论,但图 5 列出了主要属性。这里我们将深入讨论其中的少量属性。



图 5 TreeView 属性

ImageSet 它定义了要在您的 TreeView 控件中使用的一组图像。提供了大量图像集样式,最著名的有 Custom、MSDN、XPFileExplorer 和 Windows_Help。通过选取大量预定义的图像集之一,您的 TreeView 可以使用熟悉的图像并且继承这些样式。

ShowExpandCollapse起初,这看起来可能有一点奇怪,因为我们是如此习惯于看到带有展开/折叠指示符(+ 和 - 符号)的 TreeView;然而,该属性为您提供了不显示这些指示符的选项。不过,默认值为 True。

ShowLines该属性确定了是否显示将树中的子节点与其父节点连接的线条。默认值为 False。

EnableClientScript这是一个相当重要的属性,尤其是当您希望 TreeView 控件能够展开和折叠时 — 通常是这种情形(尽管我们选择不在 Northwind Traders Web 站点中执行这些操作)。该属性指示是否让客户端脚本处理用于展开和折叠节点的事件(默认情况下处理)。将该属性设置为 True 时,将避免与服务器之间进行代价昂贵的信息传递,但是如果您将该属性设置为 False,则每当用户单击树中的节点时,都需要向服务器进行回发。

ExpandDepth 在首次显示 TreeView 控件时设置展开的树级别的数目。例如,如果将该属性设置为 2,则将展开根节点及根节点下方紧邻的所有父节点。默认值为 -1,表示完全展开所有节点。

MaxDataBindDepth在将该控件绑定到数据源(如 SiteMapDataSource 控件)时,可以使用该属性来限制要绑定到该控件的树级别的数目。例如,如果将该属性设置为 2,则仅将根节点及根节点下方紧邻的所有节点绑定到 TreeView 控件。该数据源(SiteMapDataSource 控件)中的所有其余节点将被忽略,这在较深的层次结构站点映射中会比较方便。默认值为 -1,这会将数据源中的所有树级别绑定到该控件。

PopulateNodesFromClient默认情况下该属性被设置为 True,这意味着 TreeView 将由 web.SiteMap 文件中的内容静态预定义。因此,这可以避免到服务器的往返行程。为了将该属性设置为 True,还应该将 EnableClientScript 属性设置为 True;否则,将发生到服务器的回发。

DataSourceID这是要绑定到的数据源的 ID。如果您已经创建了一个 SiteMapDataSource 控件,并且希望将其用作 TreeView 的数据源,则请在此处键入 SiteMapDataSource 控件的 ID。

TreeView 控件所具有的属性要比在这里详细介绍的属性多得多,包括 SiteMapPath 控件中的相同节点样式属性(和子属性),从而使您可以对 TreeView 的行为和外观进行极为细致的控制。我们将把探索其余 TreeView 属性的工作留给您自己去完成。图 6 显示了 Northwind Traders Web 站点中某个 Web 页的源代码,使您能够对我们实现 TreeView 控件的方式有一个大致的了解。

目前的 Breadcrumb 控件

现在您很可能正在想:这些控件都很不错,我已经迫不及待地希望使用它们,但我想立即使用该功能。好,我们已经使用 ASP.NET 1.1 随意创建了一个简单的 Breadcrumb 控件,并且不是十分严格地将其设计建立在 Visual Studio 2005 SiteMapPath 控件的基础之上。通过遵循该控件的设计,我们已经创建了一条在需要从该控件切换到新控件时能够方便地进行迁移的途径。很自然地,我们调用了控件 Breadcrumb。

对于 Breadcrumb 控件,我们认为将 web.SiteMap 文件(及其内部结构)保持为从 Web 站点根目录中加载的默认数据源会是一个好主意。该示例应该使您对如何逐步完成您自己的控件有一个全面的了解,但 ASP.NET 2.0 最终版本中的实际 API 和实现可能不同。

因为 web.SiteMap 文件可能包含任意数量的非嵌套和嵌套的 元素,所以我们创建了 SiteMapNode 类以存放各个元素的属性,如 Title、Url 和 Description。因为每个 元素都可以包含其他 元素,所以我们在名为 NodeList 的类(它是其他 SiteMapNode 的集合)中添加了一个属性。 图 7 包含该类的代码。

图 8 显示了 SiteMapNodeList 类的代码,该类是从 ArrayList 继承的基本集合,但它被强类型化以仅包含 SiteMapNode。SiteMapNodeList 类是在确定某个 SiteMapNode 包含其他 SiteMapNode 时构建的,并且通过简单地向它添加一些 SiteMapNode 对象就可填充它。

与 SiteMapNodeList 类似,SiteMapPath 类是 SiteMapNode 对象的强类型化集合,并且由 Breadcrumb 控件用来获取要呈现给浏览器的实际节点(事实上,代码与 SiteMapNodeList 类几乎完全相同,除了类本身的名称以外)。例如,如果要显示给用户的路径应该是 Home > Services > Training,则 SiteMapPath 对象将包含 Home SiteMapNode、Services SiteMapNode 和 Training SiteMapNode。

注意,SiteMapPath 集合的顺序总是从根节点到当前节点。因此,Breadcrumb 控件可以轻松地确定在浏览器中呈现节点时所遵循的方向。如果将 PathDirection 属性设置为 RootToCurrent,控件将按照从第一个元素到最后一个元素的顺序读取 SiteMapPath 集合,而如果将 PathDirection 属性设置为 CurrentToRoot,控件将按照从最后一个元素到第一个元素的顺序读取该集合。

SiteMap 类是全部秘密所在;它负责从 web.SiteMap 文件加载全部节点并生成 SiteMapPath 对象,然后,将该对象公开为只读属性(参见图 9)。因为我们知道 Breadcrumb 控件只关心呈现导航路径,所以提供 SiteMapPath 属性是有意义的,原因在于本质上 SiteMapPath 是控件所关心的唯一对象。还要注意,我们的实现对图 2 中显示的 SiteMap 文件的形状具有硬编码的依赖性。为了提高健壮性,GetSiteMapPath 方法应改为使用递归。

当控件被加载时,它通过将当前 URL 和站点映射文件的名称传递给 SiteMap 类来创建该类的新实例。SiteMap 类中的所有工作都是在构造函数中完成的:首先将所有 元素加载到它们自己的 SiteMapNode 对象中(并将其链接在一起),然后生成 SiteMapPath 对象。在控件实例化 SiteMap 以后,它可以只是请求 SiteMapPath 属性以呈现给浏览器。完成这一工作的代码非常简短:

Dim uriFile As Uri = New Uri("http://localhost/nwt/web.SiteMap")
Dim uriUrl As Uri = New Uri("http://localhost/nwt/products.aspx")
Dim objSiteMap As SiteMap = New SiteMap(uriFile, uriUrl)
Dim objPath As SiteMapPath = objSiteMap.SiteMapPath

所有 SiteMapNode 的加载都是借助于 XmlTextReader 的帮助完成的,后者由一些私有 Helper 方法使用。通过检查 web.SiteMap 文件中的各个 是否为空元素,我们可以确定哪些节点是分支,以及哪些节点是叶子(分支等同于嵌套节点,而叶子是非嵌套节点)。如果确定某个节点是分支,则将它添加到父节点的 NodeList 中,但如果该节点是叶子,则将其添加到当前分支的 NodeList 中。这同时使我们可以捕获树的深度。

在将所有 SiteMapNode 加载后,将生成 SiteMapPath(这需要首先确定哪个 SiteMapNode 是当前节点)。像 Breadcrumb 实现的 Visual Studio 2005 版本一样,唯一性由给定的 URL 保证。在遍历各个 SiteMapNode 时,会将给定的 URL 与它们的 URL 属性进行比较,直至找到匹配项为止(随后将退出循环)。既然已经找到当前的 SiteMapNode,我们将再次遍历所有节点(总是从根节点到当前节点)以跟踪路径,如 GetSiteMapPath 方法中所示。

Breadcrumb 类

Breadcrumb 控件的所有服务器端代码都包含在其自定义控件类中,并且处理 web.SiteMap 文件的加载 (OnLoad) 和 HTML 的呈现 (Render)。它公开了一个枚举 — PathDirection,它含有下列值:RootToCurrent(默认值)和 CurrentToRoot。还提供了图 10 中列出的属性,它们的名称与 ASP.NET 2.0 中的名称相同。注意,每个“样式”属性的命名方式都与它们的 ASP.NET 2.0 对应属性类似,但它们的行为方式稍有不同。各个样式不再是一组属性,而是可以通过样式表设置的个别属性。

在控件的加载事件处理过程中,将创建一个 SiteMap 实例,然后控件将像刚才介绍的那样获取 SiteMapPath。接下来,Render 重写方法会按照正确的 PathDirection 将导航路径输出到浏览器中,并且带有所有关联的样式以完成其外观。图 11 显示了该类的代码,而随后的代码片段演示了如何在 Web 表单上使用该自定义控件。请观察一下这些代码与使用 ASP.NET 2.0 SiteMapPath 控件所需的代码之间的相似性。

<nwt:breadcrumb id="Breadcrumb1" runat="server" pathseparator=" -> "
    currentnodestyle="crumbNode"
    nodestyle="crumbNode"
    pathseparatorstyle="crumbPathSeparator"
    rootnodestyle="crumbNode"
    rendercurrentnodeaslink="True" />

针对 Breadcrumb 控件介绍的所有代码为您提供了一个向 Web 站点添加导航路径的简单方法。虽然还有提高其健壮性(通过缓存、错误处理和递归)的余地,但设计和编写该控件的主要目的是提高其可扩展性。

小结

正如您看到的,目前,实现一个 SiteMapPath (Breadcrumb) 控件并使其具有其 ASP.NET 2.0 相应控件所提供的某些功能需要数百行代码。要在目前实现一个与 ASP.NET 2.0 版本同样强大的 TreeView 控件,需要花费大量的时间,编写成千上万行代码。仅这一点,就足以使您为 ASP.NET 2.0 中包含的新导航控件而欢呼了,因为所有上述功能及其他功能都以现成的方式提供给您,只需要进行最少量的配置,而且更为重要的是,根本不需要自己编写代码。在您的武器库里配备了 ASP.NET 2.0 以后,您将实现您以前想都不敢想的导航目标。

DaveDonaldsonStevenDeWalt 都是一家大型保险公司的顾问 IT 架构师。工作之余,他们会忙于为他们的小型软件工作室 LoudCarrot Software 生成基于 .NET 的应用程序和服务。您可以发送电子邮件至 http://www.loudcarrot.com 与他们联系。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP