I've given this problem some thought. Here's where I'm at so far...
First, I think we need to agree that the "selected" menu item is the MenuItem in the Menu whose Selected property is set to true. This re-uses the existing .Net framework mechanism to "flag" the selected item. It is up to you to have logic to actually set this "flag" on one of your menu items.
With that in mind, I've created the following test page:
<%@ Page Language="C#" StylesheetTheme="Basic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void NavigationMenu_MenuItemClick(Object sender, MenuEventArgs e)
{
// Display the text of the menu item selected by the user.
Message.Text = "You selected " +
e.Item.Text + ".";
e.Item.Selected = true;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<!--[if lt IE 9]>
<link runat="server" rel="stylesheet" href="~/BrowserSpecificCSS/IEMenu.css" type="text/css" id="IEMenuCSS" />
<![endif]-->
<style>
.AspNet-Menu-Selected
{
background: yellow !important;
}
.AspNet-Menu-ChildSelected
{
background: red !important;
}
.AspNet-Menu-ParentSelected
{
background: green !important;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div id="SampleMenu">
<asp:menu id="NavigationMenu" onmenuitemclick="NavigationMenu_MenuItemClick" runat="server" CssSelectorClass="PrettyMenu">
<items>
<asp:menuitem text="Home">
<asp:menuitem text="Music">
<asp:menuitem text="Classical" />
<asp:menuitem text="Rock" />
<asp:menuitem text="Jazz" />
</asp:menuitem>
<asp:menuitem text="Movies" Selectable="false">
<asp:menuitem text="Action" />
<asp:menuitem text="Drama" />
<asp:menuitem text="Musical" />
</asp:menuitem>
</asp:menuitem>
</items>
</asp:menu>
</div>
<asp:label id="Message" runat="server"/>
</form>
</body>
</html>
You should be able to create a new web site (once you've installed the adapter kit's VSI), create a subfolder called Test in the root of this test web site and then place the markup shown above in a file called testMenu.aspx.
Before running this test page, though, you need to modify your menu adapter code per the instructions found here:
http://forums.asp.net/post/1295051.aspx (or view the full thread by clicking the "view complete thread" link at the top/left)
This enhances the beta 1.1 version of the menu so it can handle menus that are intended to postback to the same page (like our test page does).
Can you confirm that this test page seems to run?
If you get that far, then you are in good shape. Notice that this test page puts together a simple menu and that the page has some "extra" styles that indicate how to render the selected MenuItem (and its parent or child items). Of course, our adapter isn't (yet) fancy enough to render markup that uses these helpful (new) styles... so we need to enhance it.
In http://forums.asp.net/post/1295051.aspx you'll notice this line:
writer.WriteAttribute("class", "AspNet-Menu-Link");
There is a similar line in the "else" for the "if" that sets the class to "AspNet-Menu-NonLink." Change both of these lines so they look like this:
writer.WriteAttribute("class", GetItemClass(menu, item));
Finally, add these new methods to the MenuAdapter class:
private string GetItemClass(Menu menu, MenuItem item)
{
string value = "AspNet-Menu-NonLink";
if (item != null)
{
if (((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null)) ||
((item.Depth >= menu.StaticDisplayLevels) && (menu.DynamicItemTemplate != null)))
{
value = "AspNet-Menu-Template";
}
else if ((item.NavigateUrl.Length > 0) || item.Selectable)
{
value = "AspNet-Menu-Link";
}
if (item.Selected)
{
value += " AspNet-Menu-Selected";
}
else if (IsChildItemSelected(item))
{
value += " AspNet-Menu-ChildSelected";
}
else if (IsParentItemSelected(item))
{
value += " AspNet-Menu-ParentSelected";
}
}
return value;
}
private bool IsChildItemSelected(MenuItem item)
{
bool bRet = false;
if ((item != null) && (item.ChildItems != null))
{
bRet = IsChildItemSelected(item.ChildItems);
}
return bRet;
}
private bool IsChildItemSelected(MenuItemCollection items)
{
bool bRet = false;
if (items != null)
{
foreach (MenuItem item in items)
{
if (item.Selected)
{
bRet = true;
break;
}
bRet = IsChildItemSelected(item.ChildItems);
}
}
return bRet;
}
private bool IsParentItemSelected(MenuItem item)
{
bool bRet = false;
if ((item != null) && (item.Parent != null))
{
if (item.Parent.Selected)
{
bRet = true;
}
else
{
bRet = IsParentItemSelected(item.Parent);
}
}
return bRet;
}
Now try using the test page. Select an item and you'll see its background change color. Look at the background of the parent/children of the selected menu item. They should be shown with distinct background colors, too. Do you see that?
Remember that you can also choose a "selected" menu item when the page is first loaded by using the Selected attribute in the MenuItem tag or by heuristically deciding on a menu item to mark as selected in the page's Page_Load method, etc.
Good luck with this. I hope you get all the way through these instructions. If you run into problems, let us know. I'll try to help out again (sooner this time!).
Keep in mind that when we release a new rev of the kit it will have this fix so you won't have to suffer this pain forever.
Russ Helfand
Groovybits.com