views:

61

answers:

2

I'm trying to learn ASP.NET MVC, and I want to have menus highlighted on the item that is currently selected. I know I did this before in web forms (although I don't actually remember how at the moment, but somehow with the sitemap). But how can this be done in MVC?

It seems like such a basic thing it should be simple to do in MVC? Sure, I can do it by adding CSS rules that are coupled between a body id and an li id from the menu (#home #homeli [style as current]), but it seems that would quickly become unwieldy, especially if there are also a lot of sub menus besides the main navigation (in several of the sub pages I have a sub menu in a contentplaceholder. BTW, I guess that's the only way to do it in MVC? In web forms the sub menus too could be handled by the sitemap, but I haven't seen a way to do this in MVC...)

Any suggestions?

+1  A: 

You might want to take a look at this http://mvcsitemap.codeplex.com/. Hopefully you will be able to use it in a way you need it.

mare
Thanks, I will take a look at that. But is there really no way of doing this in a simple way in MVC itself, without third party assemblies? For a framework as sophisticated as MVC not having a way to handle basic navigation seems like a terrible oversight so it feels like I'm missing something...?
Anders Svensson
+4  A: 

Here is a tutorial that provides a very clean way to achieve this kind of menu:

http://www.dev102.com/2009/04/14/creating-a-tabbed-menu-control-for-aspnet-mvc/

The magic bit figuring out whether or not a menu item is active happens in the helper method that renders the items:

public static class MyHtmlHelper
{
   public static string TabbedMenu(this HtmlHelper helper, IEnumerable<MenuTab> tabs)
   {
       var route = helper.ViewContext.RequestContext.RouteData;
       //This is the current controller
       var controller = route.GetRequiredString("controller");
       var action = route.GetRequiredString("action");
       var menu = "\n\n<ul id=\"menu\">";

       foreach (var tab in tabs)
       {
           //if the menu controller and action match current controller and action, mark it as selected
           if (controller == tab.Controller && action == tab.Action)
               menu += "\n\t<li>" + helper.ActionLink(tab.Text, tab.Action,
               tab.Controller, new { @class = "selected" }) + "</li>";
           else
               menu += "\n\t<li>" + helper.ActionLink(tab.Text,
               tab.Action, tab.Controller) + "</li>";
       }
       menu += "\n</ul>\n\n";
       return menu;
   }
}
Igor Zevaka
Perfect, this was exactly what I was looking for. Thanks!
Anders Svensson