Building a dynamic navigation menu in ASP .NET

ASP .NET provides a few out of the box controls for navigation, but for most people, a custom navigation menu is the way to go. A common pattern that I use is creating a series of unordered lists to represent my navigation, and then I’ll use some kind of javascript to make it a little more flashy. Given the sitemap below, we’ll generate the markup needed to create a menu similar to what can be found here: Sample Menu



  
    
      
      
      
    
    
      
      
    
    
      
      
      
    
  

The markup that we’re after looks something like this:

  • Main Navigation 1
    • Sub Navigation 1
    • Sub Navigation 2
    • Sub Navigation 3
  • Main Navigation 2
    • Sub Navigation 4
    • Sub Navigation 5
  • Main Navigation 3
    • Sub Navigation 6
    • Sub Navigation 7
    • Sub Navigation 8

We can use a combination of the Sitemap objects and ASP .NET repeaters to get the desired result. If you haven’t already done so, first you must configure your site to use the sitemap. By default, your site will look for a file called Web.sitemap, or you can manually configure the sitemap in the Web.config file.

I like to put all of the code for generating the navigation inside of a user control. It always seems to make piecing together a page a little easier, and if I need to do multiple master pages, I can reuse the navigation code if needed. In order to get the markup in the right structure, I nest a repeater within another repeater:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="top-navigation.ascx.cs" Inherits="uc_top_navigation" %>

Notice that I added an OnItemDataBound handler to the main repeater. I do this so that during each iteration of the repeater, I can bind the nested repeater to the sitemap.

In the page load event of the user control, I need to bind my sitemap to the first repeater. Because of the way I’ve structured my sitemap, I want the nodes that are just below the root node. I set the source of my repeater to be these nodes, and then bind it. This gets me the top bar of my navigation, but no dropdowns just yet.

    protected void Page_Load(object sender, EventArgs e)
    {
        navBar.DataSource = System.Web.SiteMap.RootNode.ChildNodes;
        navBar.DataBind();
    }

Now that I have my top bar going across the top, it’s time to add the dropdown menus. Using the OnItemDataBound handler on the first repeater, we can get an instance of the current node that we’re working with, and use those child nodes to build out the markup for the menu. The code for this might look like this:


    protected void navBar_OnItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        SiteMapNode currentRepeaterNode = (SiteMapNode)e.Item.DataItem;
        ((Repeater)e.Item.FindControl("subNavDropdown")).DataSource = currentRepeaterNode.ChildNodes;
        ((Repeater)e.Item.FindControl("subNavDropdown")).DataBind();
    }

This gives us the markup that we need. Paired with a proper javascript file and css, this is a simple pattern to follow for creating a dynamic navigation menu.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>