This is a thread about my experience migration from the ComponentArt menu to the ASP.Net menu. There were some things that didn't seem to work as well, and other things that worked very differently. This details how I worked around these issues.
Style The Menu
The first thing that I wanted to do was to customize the menu. I started by create the menu in the master page and then assigning each style to the CssClass of each style property. So I ended up with a block of code like this:
Code:
<DynamicHoverStyle CssClass="aspnetMenu_DynamicHoverStyle" />
<DynamicMenuItemStyle CssClass="aspnetMenu_DynamicMenuItemStyle" />
<DynamicMenuStyle CssClass="aspnetMenu_DynamicMenuStyle" />
<DynamicSelectedStyle CssClass="aspnetMenu_DynamicSelectedStyle" />
<StaticHoverStyle CssClass="aspnetMenu_StaticHoverStyle" />
<StaticMenuItemStyle CssClass="aspnetMenu_StaticMenuItemStyle" />
<StaticMenuStyle CssClass="aspnetMenu_StaticMenuStyle" />
<StaticSelectedStyle CssClass="aspnetMenu_StaticSelectedStyle" />
I then wrapped the menu in a <DIV> with a class of LeftMenu.
This allowed me to style the entire menu as a group, and then each part individually. I put a picture as my background, set my font color, and set my hover look using the following CSS:
Code:
/*****************************************/
/* ASP.Net Menu Styles */
/*****************************************/
.LeftMenu
{
background-color:#ffffff;
}
.LeftMenu,
.LeftMenu a
{
color:#444444;
text-decoration: none;
text-align:left;
}
.LeftMenu tr td
{
padding-top:1px;
padding-bottom:1px;
}
.aspnetMenu_StaticHoverStyle,
.aspnetMenu_StaticHoverStyle a,
.aspnetMenu_DynamicHoverStyle,
.aspnetMenu_DynamicHoverStyle a
{
color:#ffffff;
background-color: #BB3A24;
cursor:pointer;
text-decoration:none;
}
.aspnetMenu_StaticMenuItemStyle a
{
padding-left:5px;
padding-right:5px;
}
.aspnetMenu_StaticMenuStyle
{
width:100%;
}
.aspnetMenu_DynamicMenuItemStyle a
{
padding-left:5px;
padding-right:5px;
}
.aspnetMenu_DynamicMenuStyle
{
z-index: 999;
background-image:url('images/bak_sidemenu.jpg');
background-repeat:repeat-y;
background-position:right;
}
You'll notice that a lot of classes are the same so that the menu has a uniform look and feel.
Styling Notes
Remember that almost all menu items are hyper-links, so make sure that you apply a style to <a> tags. You'll notice that I often included the a selector in with my class selectors to make sure that the links were styled along with other text.
Also noteworthy is that if you use an XML file to apply your menu items you must have a single root entry. If you add the items directly to the menu you can have as many first-level items as you want.
When working with the menu named aspnetMenu you'll see that you can't add any menu items. That menu is the one that is populated via page.menu.xml.config and any items you define will be remove when the items from that config file are added.
NOTE: The above doesn't work. See below.
I was befuddled for a long time because according to all the documentation the above should have worked, but it didn't. I looked more closely at the sample provided by the ASPDNSF folks and found a comment saying that the StatisHoverStyle and DynamicHoverStyle couldn't be added declaratively and that they would be added later via script. I also noted that the sample CSS that the provided mentioned something about naming conventions. Naming conventions didn't work for me because I needed reusable styles for my multiple menus that I replace based on the page the user is in (see this thread). That caused me to add the following code:
Code:
.aspnetMenu_StaticMenuItemStyle:hover,
.aspnetMenu_StaticMenuItemStyle:hover a,
.aspnetMenu_DynamicMenuItemStyle:hover,
.aspnetMenu_DynamicMenuItemStyle:hover a
{
color:#ffffff;
background-color: #BB3A24;
cursor:pointer;
text-decoration:none;
}
This code caused the menu to work properly, though it is a little bit of a hack.
Make the Hover Sticky
The next feature that I wanted to add was the ability to have the hover style stick when the user moved to a child menu. After a considerable amount of work I was able to get some JavaScript together to enable this. I put the JavaScript in a file called menuOverride.js and put it in the jscripts folder. The code in that file is:
Code:
/*
Code based on
http://blogs.msdn.com/howard_dierking/archive/2007/04/23/polymorphic-javascript-well-kind-of.aspx
http://blogs.vertigo.com/personal/aanttila/Blog/archive/2007/03/14/javascript-differences-in-firefox-and-internet-explorer.aspx
http://www.javascriptkit.com/javatutors/navigator.shtml
*/
var fw_Menu_Unhover;
var fw_Menu_HoverDynamic;
function SetupInterceptors() { // called by onload event
fw_Menu_HoverDynamic = Menu_HoverDynamic;
Menu_HoverDynamic = my_Menu_HoverDynamic;
fw_Menu_Unhover = Menu_Unhover;
Menu_Unhover = my_Menu_Unhover;
}
function my_Menu_HoverDynamic(item) {
fw_Menu_HoverDynamic(item);
var x = Menu_FindParentItem(item);
if (x && x.tagName.toLowerCase() != "body") {
switch (true) {
case (/MSIE (\d+\.\d+);/.test(navigator.userAgent)): //test for MSIE x.x
x.fireEvent("onmouseover");
break;
case (/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)):
//opera should use the default, but it appears broken
//if you uncomment the next line it will work without the mouse over effect
//break;
default:
var mouseEvent = window.document.createEvent("MouseEvent");
mouseEvent.initEvent("mouseover", true, true);
x.dispatchEvent(mouseEvent);
break;
}
}
}
function my_Menu_Unhover(item) {
fw_Menu_Unhover(item);
var x = Menu_FindParentItem(item);
if (x && x.tagName.toLowerCase() != "body") {
switch (true) {
case (/MSIE (\d+\.\d+);/.test(navigator.userAgent)): //test for MSIE x.x
x.fireEvent("onmouseout");
break;
case (/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)):
//opera should use the default, but it appears broken
//if you uncomment the next line it will work without the mouse over effect
//break;
default:
var mouseEvent = window.document.createEvent("MouseEvent");
mouseEvent.initEvent("mouseout", true, true);
x.dispatchEvent(mouseEvent);
break;
}
}
}
I then linked this file to my master page with the following line in the head:
Code:
<script type="text/javascript" src="jscripts/menuOverride.js"></script>
NOTE: The above doesn't work. See below.
Much to my disappointment the above didn't work reliably and that is due to the hack put in place above to get the hover styles to work. After much work I found that problem had to do with the name of the style that was being added to the menu container to apply the hover style. I traced through the code and found that if I declaratively added in DynamicHoverStyle and StaticHoverStyle things would get better.
NOTE: The above doesn't work. See below.
There is a reason that comment about not adding in the DynamicHoverStyle and StaticHoverStyle declaratively is in the sample template; it doesn't work. After going through more code I was able to figure out why. It has to do with those styles being applied again in MasterPageBase.vb just as the comment said they would be.
I commented out the following lines (about line 283):
Code:
' now for the custom asp.net Menu javascript
'script.AppendFormat(" if({0}_Data) {{" & vbLf, menuId)
'script.AppendFormat(" {0}_Data.hoverClass = '{0}_DynamicHoverStyle';" & vbLf, menuId)
'script.AppendFormat(" {0}_Data.hoverHyperLinkClass = '{0}_DynamicHoverStyle';" & vbLf, menuId)
'script.AppendFormat(" {0}_Data.staticHoverClass = '{0}_StaticHoverStyle';" & vbLf, menuId)
'script.AppendFormat(" {0}_Data.staticHoverHyperLinkClass = '{0}_StaticHoverStyle';" & vbLf, menuId)
'script.AppendFormat(" }}" & vbLf)
I recompiled that file and tried the site and everything worked just fine.
NOTE: The above is a modification of the source and so may have unforeseen side-effects. See below.
I'm not sure why the developers decided to not use the DynamicHoverStyle and StaticHoverStyle in the master page and instead to add them in via JavaScript later on. I tested the above on Firefox, IE, Chrome, and Opera. Opera has issues, but I've already filed a bug report with the Opera developers as the issue appears to be with the browser because half of the code works and none of it generates errors.