RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Nine ASP.NET Site Navigation Problem Solutions: Part 1 : Page 2

Find out how to use ASP.NET 2.0's site navigation controls to not only make building site navigation displays simple, but also solve real-world problems, such as hiding selected pages, or displaying "breadcrumbs."

#2: Active Buckets: The Plot Thickens
Most sites display active buckets differently from inactive buckets in order to help users identify where they are in the site. But what does active mean? Active pages (the term is not restricted to buckets)contain a direct lineage to the current page. For example, notice that the Home bucket in Figure 1 is white instead of blue. This is because the Home page is a bucket and the parent of Site Map. If the Site Map page resided within some other bucket, then the Home would be blue, and the other bucket would be white.

Determining ancestry required a custom approach in ASP.NET 1.1. ASP.NET 2.0 simplifies the task with the SiteMapNode.IsDescendantOf() method.

Consider the following page snippet:

   <asp:Repeater ID="rpt" runat="server" DataSourceID="dsBuckets">
       IsBucketActive((SiteMapNode)Container.DataItem) ?
       // if the current page belongs to the current bucket
       "[display active image]" :
       // else if the current page does not belong 
       // to the current bucket   
       "[display regular image]"
The repeater's ItemTemplate calls the IsBucketActive() method in the code-behind and passes in the current SiteMapNode. The IsBucketActive() function then returns true if CurrentNode.IsDescendentOf(nodeBucket):

   protected bool IsBucketActive(SiteMapNode nodeBucket) {
     // pages that don't contain an item in Web.sitemap return null
     if (SiteMap.CurrentNode == null)
       return false;
       return SiteMap.CurrentNode.Equals(nodeBucket) || 
IsDescendantOf() combined with the SiteMap.CurrentNode property packs a powerful punch. And since the default XmlSiteMapProvider holds everything in memory, it's fast too. The next solution demonstrates a vertically-oriented navigation, which requires nesting Repeaters.

#3: Putting Pails inside Buckets
Vertical navigations often display buckets (top-level pages), then pails (second-level pages) under the active bucket, and then sometimes tertiary pages under active pails (see Figure 2). But Repeater's don't display hierarchical data, right? Actually, they can if you nest Repeaters and use the data binding syntax (see my article Nested DataGrids Simplify Hierarchical Data Display for more details).

Figure 2: Vertically-oriented Navigation: The navigation bar on the left side of the page in the solution that accompanies this article demonstrates a vertically-oriented navigation.
The code for this solution might look like:

   <asp:Repeater ID="Buckets" runat="server" 
       <%# IsBucketActive((SiteMapNode)Container.DataItem) ?
           String.Format("<a href=\"{0}\"><b>{1}</b></a><br />," 
              ((SiteMapNode)Container.DataItem).Title) :
           String.Format("<a href=\"{0}\">{1}</a><br />," 
       <asp:Repeater ID="Pails" runat="server" DataSource='<%# 
         ((SiteMapNode)Container.DataItem).ChildNodes %>' 
         Visible='<%# IsBucketActive(
           <%# String.Format("&nbsp;&nbsp;<a href=\"{0}\">{1}
             </a><br />,"
            ((SiteMapNode)Container.DataItem).Title) %>
With this approach the nested repeater retrieves the current SiteMapNode of the outer repeater and binds to its children via the ChildNodes() function. The nested repeater's Visible property combined with the IsBucketActive() function allows only active buckets to display their pails. The next solution shows another common variation for displaying pails.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date