Manipulating the SiteMapDataSource for ASP.NET 2.0 Menus

Link. May 16, 2006. Comments [2]. Posted in: .NET | ASP.NET

I've been spending some time with ASP.NET 2.0 lately. There are many interesting and very useful new features (Master Pages for example being one of my favourites). Some features however require some more effort to make them work as you'd like (as everything, I guess). Two of those are the Menu and the SiteMapDataSource controls.

Basically, what I was trying to achieve was a very basic top-level, horizontal navigation bar for the site I was working on. The first hurdle was getting the Menu control to generate even remotely useful HTML code, as by default it will generates a mess of nested HTML tables somewhat awkward to style using CSS. Fortunately, I had read ScottGu's entry on the CSS control adapters toolkit, so I downloaded and took a look at the code and was able to use that to instead generate <ul> and <li> HTML tags that were be more workable. I did make a few modifications to the default adapter included in the tooklit to wrap my horizontal menu in <span> tags instead of <div> tags, which allowed me to put some other stuff next to the menu I needed.

With that out of the way, I was running into a little bit of a snag. SiteMaps can only have a single root, which was ok by me and suited the site just fine. The problem was that I wanted the navigation bar to include both the top-level node in the SiteMap (i.e. "Home") as well as all the entries in the second level of the SiteMap (i.e. the real content pages). Having the SiteMapDataSource control driving the menu ignore the root of the SiteMap was not an option, and leaving it as is didn't fit the bill, either.

I could've just used an external XML data source instead, but the SiteMap really worked for my purposes (and was used to drive a SiteMapPath control as well), and well, I'm a sucker for punishement and wanted to check out if I could beat this thing into submition. As it turns out, I could :-)

What I did probably can be called an ugly hack: I created a SiteMapDataSource-derived control that overrides the GetHierarchicalView() method. In it, I grab the SiteMap, clone the root, remove the children and then create a new SiteMapNodeCollection that contains both the cloned root as well as the original second-level items, then return a new SiteMapHierarchicalDataSourceView created from that. Strangely enough it works. Here's what the code looks like (sort of):

public class CustomSiteMapDataSource : SiteMapDataSource
{
   protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
   {
      SiteMapNode root = Provider.RootNode;
      SiteMapNode newRoot = root.Clone();
      newRoot.ChildNodes = new SiteMapNodeCollection();
      SiteMapNodeCollection collection = new SiteMapNodeCollection();
      collection.Add(newRoot);
      collection.AddRange(root.ChildNodes);
 
      return new SiteMapHierarchicalDataSourceView(collection);
   }
}

I then just had the Menu control get it's data from a CustomSiteMapDataSource object instead of a normal SiteMapDataSource. Note the code above doesn't have any decent error checking and most certainly will always return just the two top levels of the menu, but it worked for my purposes.



Wednesday, June 21, 2006 5:06:03 PM (SA Pacific Standard Time, UTC-05:00)
Why not just set the "StaticDisplayLevels" property on your menu control to "2"? That's what I do to show the top 2 levels as one level across my horizontal menu.
Jason
Wednesday, June 21, 2006 6:35:47 PM (SA Pacific Standard Time, UTC-05:00)
Jason,
Maybe I hosed up, but from my tests, StaticDisplayLevels doesn't force all items to display at the "same level", it just forces the menu to render those levels in the static (i.e. always visible) part of the menu. I might be wrong, though.
Comments are closed.

About

Tomas Restrepo is a software developer located in Colombia, South America. His interests include .NET, Connected Systems, PowerShell and lately dynamic programming languages. More...

tomasrestrepo @ twitter My Flickr photostream My saved links on delicious My Technorati Profile

email: tomas@winterdom.com
msn: tomasr@passport.com

View my profile on LinkedIn

MVP logo

Syndicate

Ads


Links

Categories

Statistics

Total Posts: 1020
This Year: 90
This Month: 9
This Week: 0
Comments: 791

Blogroll

Post Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.1.8102.813

Sign In