Navigation





Navigation

The importance of good navigation on a site cannot be underestimated. It doesn't matter how great your site looks or how well it was developed—if it's hard to navigate, users won't like using it. It's easy to see how seriously navigation is taken just by looking at the number of menu controls that have been written since ASP.NET 1.0 was released. There are now controls that use tree views, vertical expansion, horizontal layouts, flashy graphics, and so on.

Providing a good menu isn't the end of site navigation because it's important to ensure visitors know where they are within the site hierarchy. Too often we see sites with pages three or four levels deep within the menu structure, but when we navigate to those pages there's no indication of where we are. We are left wondering how to navigate back up the structure; at worst, we have to go back to the home page to navigate down again.

Site Maps

There are plenty of ways to implement navigation on a site, but none are an intrinsic part of ASP.NET 1.x. With ASP.NET 2.0, new controls and configuration files provide a set way to define site structure and techniques for displaying the navigation information and extracting the current navigation path.

Like the rest of ASP.NET, the architecture for navigation has been broken down into logical parts, allowing customization. First, there is a configurable provider supplying the site map information, and then a set of controls that can take advantage of the data supplied by the provider. The provider not only exposes the site structure to other controls but also keeps track of the current navigation, allowing pages to identify where in the hierarchy they are. The entire structure and the current details can be exposed to users by binding controls to the provider. This pluggable architecture means that data defining the structure of a site can come from any data source—the site map provider is the link between the data and the navigation within a site.

Site Map Providers

A site map provider is a data provider that exposes the site structure by way of a set interface. Site maps are pluggable within the application configuration file, within the <system.web> section. The syntax for this section is shown in Listing 5.9.

Site Map Configuration Syntax

<siteMap

    defaultProvider="String"

    enabled="[true|false]">

  <providers>

    <add

        type="String"

        name="String"

        description="String"

        provider-specific-configuration />

    <remove

        name="String" />

    <clear>

  </providers>

</siteMap>


The attributes for the siteMap element are shown in Figure. The attributes for the providers element are shown in Figure.

siteMap Configuration

Attribute

Description

defaultProvider

The name of the default provider. This should match one of the names supplied in the providers section.

enabled

A Boolean value indicating whether or not site maps are enabled.


SiteMap providers Configuration

Attribute

Description

name

The name of the site map provider.

description

A description of the provider.

type

A string containing the full .NET type of the provider.


With the beta release of ASP.NET 2.0, the only provider is the XmlSiteMapProvider (in System.Web), allowing site navigation structure to be stored in an XML file. For a full description of the type attribute, see the machine.config file. The XmlSiteMapProvider has one provider-specific attribute, as shown in Figure.

XmlSiteMapProvider-Specific Attribute

Attribute

Description

siteMapFile

The name of the XML file containing the site structure. The filename is configured as web.SiteMap.


With the beta release of ASP.NET 2.0, the only provider is the XmlSiteMapProvider (in System.Web), allowing site navigation structure to be stored in an XML file. For a full description of the type attribute, see the machine.config file. The XmlSiteMapProvider has one provider-specific attribute, as shown in Figure.

The pluggable architecture makes it extremely easy to add support for additional methods of site map storage. For example, you could write a Front Page Server Extensions site map provider to read the site structure from the format used by Microsoft Front Page, or perhaps one to build the structure from the file system, directly reading the names of the files and directories. To write your own site map provider you need to inherit from the abstract class SiteMapProvider. A discussion of this is outside the scope of the book, but details of the class can be found in the documentation.

Site Map Configuration Files

The XmlSiteMapProvider defines a set schema for the web.SiteMap file, as shown in Listing 5.10.

XmlSiteMapProvider Schema

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

           elementFormDefault="qualified">

  <xs:element name="siteMap">

    <xs:complexType>

      <xs:sequence>

        <xs:element ref="siteMapNode"

                    maxOccurs="unbounded"/>

      </xs:sequence>

    </xs:complexType>

  </xs:element>

  <xs:element name="siteMapNode">

    <xs:complexType>

      <xs:sequence>

        <xs:element ref="siteMapNode" minOccurs="0"

                    MaxOccurs="unbounded"/>

      </xs:sequence>

      <xs:attribute name="url" type="xs:string"/>

      <xs:attribute name="title" type="xs:string"/>

      <xs:attribute name="description" type="xs:string"/>

      <xs:attribute name="roles" type="xs:string"/>

      <xs:attribute name="SiteMapFile" type="xs:string"/>

      <xs:attribute name="Provider" type="xs:string"/>

    </xs:complexType>

  </xs:element>

</xs:schema>


This defines a structure consisting of a root siteMap element, with the site structure being contained by siteMapNode elements. There has to be one top-level siteMapNode element, and within that can be any number of siteMapNode elements of any depth. The attributes for the siteMapNode element are shown in Figure.

SiteMapNode Attributes

Attribute

Description

url

The URL to be used to navigate to the node. This must be unique within the entire site map file.

title

The title of the node.

description

A description of the node.

roles

A list of roles allowed to view the node. Multiple roles can be separated by semicolons (;) or commas (,).

SiteMapFile

An external file containing additional siteMap nodes.

Provider

The name of the site map provider that will supply additional nodes specified in SiteMapFile


The use of SiteMapFile allows the site map information to be split among different sources. This is especially useful when different divisions supply sections of a corporate site—each part of the site map can be authored independently and even stored in different providers.

Listing 5.11 shows a sample site map file. To create one within Visual Studio 2005 you simply create a new XML file and call it web.SiteMap—there isn't a template for this.

Sample web.SiteMap File

<?xml version="1.0" encoding="utf-8" ?>

<siteMap>

  <siteMapNode title="Home" url="sitemaps.aspx">

    <siteMapNode title="A" url="sitemapsA.aspx">

      <siteMapNode title="1" url="sitemapsA1.aspx" />

      <siteMapNode title="2" url="sitemapsA2.aspx" />

      <siteMapNode title="3" url="sitemapsA3.aspx" />

    </siteMapNode>

    <siteMapNode title="B" url="sitemapsB.aspx">

      <siteMapNode title="4" url="sitemapsB4.aspx">

        <siteMapNode title="a" url="sitemapsB4a.aspx" />

        <siteMapNode title="b" url="sitemapsB4b.aspx" />

      </siteMapNode>

      <siteMapNode title="5" url="sitemapsB5.aspx" />

      <siteMapNode title="6" url="sitemapsB6.aspx" />

    </siteMapNode>

    <siteMapNode title="C" url="sitemapsC.aspx" />

  </siteMapNode>

</siteMap>


This provides the following structure for the site:






Home

  A

    1

    2

    3

  B

    4

      a

      b

    5

    6

  C


Using a Site Map File

Once the structure of your site is defined in the site map file, you need a way to make use of it. For this you use a SiteMapDataSource control, which provides data access to the site map data, and then a control to display that data. From within Visual Studio 2005 you can just drag a SiteMapDataSource control onto the design surface—there's no need to set any properties because it defaults to using web.SiteMap as its data source. You can then drag a TreeView or Menu control onto the page and set the DataSourceId property to the id of the SiteMapDataSource control. Figure, for example, shows how our Big Corp site could be constructed using a single menu.

10. A menu bound to a SiteMapDataSource

graphics/05fig10.gif


Other controls can be bound to site map data, but in the beta release, the Menu and TreeView controls provide the best option because of their hierarchical display.

Site Maps in Depth

At its simplest, the use of site maps needs nothing more than what we just discussed, but there's actually more to them. Adding a SiteMapDataSource control to a page provides all that's needed for site map handling, but there are properties that allow for more control over how the data is supplied from the SiteMapDataSource to controls. For example, Listing 5.12 shows the syntax of the SiteMapDataSource control.

SiteMapDataSource Syntax

<asp:SiteMapDataSource docEmphasis">String" runat="server"

  SiteMapProvider="String"

  ShowStartingNode="[true|false]"

  StartFromCurrentNode="[true|false]"

  StartingNodeOffset="Integer"

  StartingNodeUrl="String"

/>


Figure lists the attributes.

SiteMapDataSource Attributes

Attribute

Description

SiteMapProvider

Specifies the name of the provider supplying the site map data.

ShowStartingNode

Indicates whether or not the starting node is shown. The default value is True.

StartFromCurrentNode

Indicates whether or not the data exposed starts from the current node. The default value is False.

StartingNodeOffset

Specifies the node depth at which to start representing data. The default is 0, which is the first node.

StartingNodeUrl

Specifies the URL of the node at which to start representing data.


The effects of some of these properties may not be immediately obvious; the best way to understand them is to walk through an example that allows setting of the properties, as shown in Figure. This scenario uses the site map code shown earlier in Listing 5.11. There are two navigation controls, a TreeView and a Menu, and for clarity all nodes are made visible.

11. Setting the site map's properties

graphics/05fig11.gif


Starting from the Current Node

The StartFromCurrentNode property indicates whether the data exposed from the site map starts at the currently selected node. For example, in Figure the StartFromCurrentNode property has been set to True, and we have navigated to page B. We can see that for both navigation controls only the nodes from the current node are shown.

12. Setting the StartFromCurrentNode property to True

graphics/05fig12.gif


Disabling the Starting Node

Setting the ShowStartingNode property to False means that the starting node isn't shown. It's important to remember that this doesn't mean the root node; it's the node from which navigation starts. For example, Figure shows this property set to False when the StartFromCurrentNode property is also set to False. The current page is B, but notice that B doesn't show in the navigation because it is the starting node.

13. Setting the ShowStartingNode property to False

graphics/05fig13.gif


Setting the Starting Node Offset

The StartingNodeOffset property defines the offset from the starting node and can be a positive or negative number. For example, Figure shows a StartingNodeOffset of -2 with navigation on page B4a. You'd expect the navigation controls to show only siblings of the a node (because the StartFromCurrentNode property is also True), but the offset of -2 pushes the node up two levels. A positive number would push the navigation down levels in the hierarchy.

14. Setting the StartingNodeOffset Property

graphics/05fig14.gif


Setting the Starting Node URL

The StartingNodeUrl property allows us to set the starting point, given the URL of a page. Since URLs in the site map file must be unique, this allows us to navigate to a given node knowing only the URL, rather than its location in the hierarchy.

Showing a Navigation Path

When a site map provides the navigational architecture for a site, it's easy to add features that take advantage of this. With a hierarchy three deep or more, it has always been hard for users to remember where they are within that structure, so the idea of breadcrumbs came about, laying a trail of the path back to the root of the site.

With ASP.NET 2.0 this is simple. We have the SiteMapPath control, which automatically hooks into the site map architecture, so all you have to do is drop it on a page, as shown in Figure.

15. The SiteMapPath control

graphics/05fig15.gif


This figure shows the default implementation, just from adding the following line of code to our page:






<asp:SiteMapPath  runat="server" />


To use the SiteMapPath control you don't need a SiteMapDataSource control because it works directly with the site map provider.

The current node is shown as simple text, and parent nodes are shown as hyperlinks, allowing quick navigation up the tree. The text for the tooltip is set to the description attribute from the site map file.

There are plenty of ways to customize this control to fit it to your site. The syntax is shown in Listing 5.13.

SiteMapPath Syntax

<SiteMapPath docEmphasis">String" runat="server"

  CurrentNodeStyle="Style"

  CurrentNodeTemplate="Template"

  HoverNodeStyle="Style"

  NodeStyle="Style"

  NodeTemplate="Template"

  ParentLevelsDisplayed="Integer"

  PathDirection="[CurrentToRoot|RootToCurrent]"

  PathSeparator="String"

  PathSeparatorStyle="Style"

  PathSeparatorTemplate="Template"

  RenderCurrentNodeAsLink="Boolean"

  RootNodeStyle="Style"

  RootNodeTemplate="Template"

  ShowToolTips="Boolean"

  SiteMapProvider="String"

  />


These are just the unique properties for this control, described in Figure. All other properties are inherited and are described in the documentation.

SiteMapPath Properties

Property

Description

CurrentNodeStyle

Sets or returns the Style object that defines how the current node is displayed.

CurrentNodeTemplate

Sets a Template, allowing customization of how the current node is displayed.

CurrentNodeTemplate

Sets a Template, allowing customization of how the current node is displayed.

HoverNodeStyle

Sets or returns the Style to be used when hovering over nodes.

NodeStyle

Sets or returns the Style to be used for nodes.

NodeTemplate

Sets a Template, allowing customization of how a node is displayed.

ParentLevelsDisplayed

Sets or returns the number of parent levels displayed. By default all parent levels are displayed.

PathDirection

Gets or sets the direction in which the nodes are displayed. This can be one of the PathDirection enumerations, whose values are

  • CurrentToRoot: The current node is shown on the left, and parent nodes are shown on the right.

  • RootToCurrent: The parent node is shown on the left, and parent nodes are shown on the right. This is the default value.

Setting the direction has no effect on the separator between nodes.

PathSeparator

Sets or returns a String to be used as a separator between nodes. This is replaced by the contents of the PathSeparatorTemplate if present. The default is >.

PathSeparatorStyle

Sets or returns the Style to be used for the PathSeparator string.

PathSeparatorTemplate

Sets a Template, allowing customization of the node separator.

RenderCurrentNodeAsLink

Sets or returns a Boolean that indicates whether or not the current node is rendered as a hyperlink. The default value is False.

RootNodeStyle

Sets or returns the Style to be used for the root node. Any Style values set here override those set in the NodeStyle property.

RootNodeTemplate

Sets a Template, allowing customization of the root node.

ShowToolTips

Sets or returns a Boolean indicating whether or not tooltips are shown on hyperlinks.

SiteMapProvider

Sets or returns a String indicating the site name of the provider supplying the site map data.


These properties give a great deal of flexibility in how the navigation path is shown. For example, consider the code shown in Listing 5.14.

Setting the SiteMapPath Properties

<asp:SiteMapPath  runat="server"

    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">

  <PathSeparatorTemplate>

      <asp:Image runat="server" ImageUrl="arrow.gif"/>

  </PathSeparatorTemplate>

</asp:SiteMapPath>


This defines styles for the nodes and a separator that uses a custom image. The results are shown in Figure.

16. A customized SiteMapPath control

graphics/05fig16.gif


Notice that the root node is underlined even though it wasn't specified as part of the RootNodeStyle—the underlining was inherited from the NodeStyle.

SiteMapPath Events

The SiteMapPath is built dynamically from the data held by the underlying site map provider. As the tree of nodes is traversed, each item in the path, from the root node to the current node, is added to the Controls collection of the SiteMapPath control. Like other collection controls (such as the DataList or DataGrid), two events are fired when items are either created (ItemCreated) or bound (ItemDataBound) to the SiteMapPath. The signature for these events is the same:












Sub eventName(Sender As Object, E As SiteMapNodeItemEventArgs)


SiteMapNodeItemEventArgs has one property, Item, which returns an object of type SiteMapNodeItem, which in turn has three properties, as described in Figure.

SiteMapNodeItem Properties

Property

Description

ItemIndex

The zero-based index number of the item being added.

ItemType

The type of node being added, which can be one of the SiteMapNodeItemType enumerations:

  • Current: Indicates the current node (page) within the navigation path.

  • Parent: Indicates a parent of the current node. All nodes between the current node and the root node are parent nodes.

  • PathSeparator: Indicates a separator between nodes.

  • Root: Indicates the root node of the navigation path.

SiteMapNode

The SiteMapNode that represents the node being added to the SiteMapPath.


Intercepting the ItemCreated and ItemDataBound events gives you a chance to change the default behavior as the items are created.

The SiteMapNode Object

When the site map is constructed from the data provider, each of the items is built into a SiteMapNode object. These in turn are added to a SiteMapNodeCollection, which therefore represents all pages within a Web site. The SiteMapNode object provides links to nodes up, down, and next to it in the hierarchy and thus can be used to build a treelike structure. The ItemCreated event of the SiteMapPath object allows access to the SiteMapNode, which has the properties detailed in Figure.

SiteMapNode Properties

Property

Description

Attributes

Returns a collection of additional attributes applicable to the node. For the XmlSiteMapProvider, the list of attributes maps to existing properties, namely Title, Description, Url, Attributes, Roles, and Keywords.

ChildNodes

If applicable, returns a SiteMapNodeCollection containing child nodes of the current node.

Description

Returns the description of the current node.

HasChildNodes

Indicates whether or not the current node has any child nodes.

NextSibling

Returns the next node on the same level as the current node, or returns null (Nothing in Visual Basic) if there is no next node.

ParentNode

Returns the parent node of the current node, or returns null (Nothing in Visual Basic) if there is no parent node (i.e., the current node is the root node).

PreviousSibling

Returns the previous node on the same level as the current node, or returns null (Nothing in Visual Basic) if there is no previous node.

Roles

Returns an IList containing the roles applicable to the current node.

RootNode

Returns the root node.

Title

Returns the title of the current node.

Url

Returns the URL of the current node.


There are three methods for the SiteMapNode object, as described in Figure.

SiteMapNode Methods

Method

Description

GetAllNodes

Returns a SiteMapNodeCollection containing all child nodes of the current node.

GetDataSourceView

Returns a SiteMapDataSourceView, which is a view of the underlying site map data. This is useful for control developers who wish to interface to the site map architecture.

IsDescendantOf

Indicates whether or not the current node is a descendant of a supplied node.


Accessing the Site Map at Runtime

So far we've seen the site map be used by controls, but it can also be accessed directly because it is exposed through a static page property called SiteMap. For example, to access the current node within the site map, you can use the following code:






Dim currNode As SiteMapNode



currNode = SiteMap.CurrentNode


This means that even if you aren't using a SiteMapPath control, you can easily build links pointing back to the hierarchy, as shown in Listing 5.15.

Using the SiteMap Property of the Page

<script runat="server">



Sub Page_Load(Sender As Object, E As EventArgs)



  ParentLink.NavigateUrl = SiteMap.CurrentNode.ParentNode.Url



End Sub



</script>



<form runat="server">



  <asp:HyperLink  Text="Go Back" />



</form>


Figure details the properties of the SiteMap class.

SiteMap Class Properties

Property

Description

CurrentNode

Returns a SiteMapNode object representing the current page.

Provider

Returns the site map provider.

Providers

Returns a collection (SiteMapProviderCollection) of all site map providers.

RootNode

Returns a SiteMapNode object representing the root node.


These properties give you access to the site map details and allow you to interface into it at the programmatic level, in case more flexibility is required than the standard server controls provide.

Navigation Controls

The two primary controls for navigation are the TreeView and Menu, both of which can be bound to a SiteMapDataSource control. Both of these controls provide a great deal of options for customization, supporting the standard AutoFormat options for easy styling, as well as support for styles and templates. For this support there are a number of style properties for the controls, which can be added either to the control declaration or as subelements. Both controls support a variety of these style elements to allow fine-grained customization of the control.

Styling the TreeView Control

The TreeView control allows styles to be defined for various types of nodes as well as for the level at which the node appears. For example, consider Listing 5.16, which shows the use of some of these style elements. Notice that the LevelStyles element is a collection of TreeNodeStyle elements; these are assigned to consecutive levels in the tree, so the first level gets a red background and the second a green one.

Styling a TreeView Control

<asp:TreeView  runat="server">

  <LevelStyles>

    <asp:TreeNodeStyle BackColor="Red" />

    <asp:TreeNodeStyle BackColor="Green" />

  </LevelStyles>

  <HoverNodeStyle Font-Underline="True" />

</asp:TreeView>


Figure shows the allowed style elements.

TreeView LevelStyles Elements

Element

Description

HoverNodeStyle

Defines the format for when the cursor is hovering over a node.

LeafNodeStyle

Defines the style for a leaf node, that is, a node with no children.

LevelStyles

Defines a collection of TreeNodeStyle elements, each of which matches to a level in the tree.

NodeStyle

Defines the general style for a node, unless overridden by another style.

ParentNodeStyle

Defines the style for a node that contains children, unless overridden by another style.

RootNodeStyle

Defines the style for the root node, unless overridden by another style.

SelectedNodeStyle

Defines the style for a selected node.


Additional properties are Nodes, which defines a collection of TreeNode elements for declarative assignment of nodes, and Bindings, which defines a collection of TreeNodeBinding elements to bind to data sources. The default bindings when used with a data source control are the following.

  • The title is shown as the text of the node.

  • The description is shown as the tooltip text of the node.

  • The URL is the navigation path of the node.

Styling the Menu Control

Like the TreeView, the Menu control also supports the notion of style elements, but these are a little more complex. This is because the Menu can be either a static or a dynamic Menu, or a combination of both. By default only the first node is static, always appearing on the page; all other nodes are dynamic and appear as fly-out windows. The StaticDisplayLevels property can be set to define the number of levels that appear statically, and these by default are indented so the hierarchical structure is not lost. To cater to this mixed mode of operation there are style elements for the static and dynamic portions of the menu, as well as the individual items that appear on those menus. For example, consider Listing 5.17, which defines style elements for submenus. Notice that the first submenu doesn't override any style values already set; it is simply a placeholder to allow styles to be set for the second and third submenu items.

Styling a Menu Control

<asp:Menu  runat="server" staticDisplayLevels="2">

  <LevelSubMenuStyles>

    <asp:SubMenuStyle />

    <asp:SubMenuStyle BackColor="green" />

    <asp:SubMenuStyle BackColor="red" />

  </LevelSubMenuStyles>

  <StaticHoverStyle ForeColor="White" BackColor="#990000" />

</asp:Menu>


Figure defines the style properties in more detail.

Menu Style Elements

Element

Description

DynamicHoverStyle

Defines the style used when hovering over dynamic menu items.

DynamicMenuItemStyle

Defines the style for individual menu items on a dynamic menu.

DynamicMenuStyle

Defines the style for a dynamic menu.

DynamicSelectedStyle

Defines the style for a selected item in a dynamic menu.

LevelMenuItemStyles

Defines a collection of MenuItemStyle elements that define the style for each menu item.

LevelSelectedStyles

Defines a collection of MenuItemStyle elements that define the style for selected menu items.

LevelSubMenuStyles

Defines a collection of SubMenuStyle elements that define the style for the submenu as a whole.

StaticHoverStyle

Defines the style used when hovering over static menu items.

StaticMenuItemStyle

Defines the style for individual menu items on a static menu

StaticMenuStyle

Defines the style for a static menu.

StaticSelectedStyle

Defines the style for selected items on a static menu.


Similar to the TreeView, the Menu can also have items defined declaratively, via the Items element, which contains a collection of MenuItem elements. Explicit binding can be done via the DataBindings collection.


     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows