Click here to Skip to main content
15,886,110 members
Articles / Web Development / ASP.NET

AMenu - A Simple .NET Vertical Menu

Rate me:
Please Sign up or sign in to vote.
4.88/5 (26 votes)
8 Oct 2009CPOL4 min read 64K   3.1K   100   4
A CSS based .NET vertical menu control.

AMenu screenshot

Introduction

AMenu is a simple .Net wrapper for a CSS based "flyout" vertical menu. There are many good articles on the Web describing the workings of CSS menus, e.g.: http://www.seoconsultants.com/css/menus/tutorial. Basically, the menu is implemented using nested UL elements, where each LI contains a hyperlink.

The primary function of the CSS is to hide/show the submenus, and to implement the desired layout. Hiding is done by using either {disaply:none} on the UL element, or moving the element off the screen {left:-5000px}. The submenus are shown by specifying their position in the hover pseudo class using a child selector: li:hover > ul {left:100%}.

The following is a working sample demonstrating the concept. Please note, the IE6 specific code has been ommited for clarity; This sample will work on all browser but IE6.

File test.htm:

HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>AMenu test</title>
<link href="amenu.css" type="text/css" rel="stylesheet" />
</head>
<body>

<div id="Menu3" class="amenu">
  <ul class="top">
    <li class="vpadding_top" />
    <li><a href="#">Parts Catalog ...</a>
      <ul class="sub">
        <li class="vpadding_top">
        <li><a href="#">Batteries</a></li>
        <li><a href="#">Alternators</a></li>
        <li class="vpadding_bottom" />
      </ul>
    </li>
    <li class="vpadding_bottom" />
  </ul>
</div>

</body>
</html> 

Implementation

The menu is implemented as three WebControl-derived componenets: AMenu, AMenuSub, MenuLink, and the associated style sheet amenu.css.

The AMenu class is responsible for rendering the DIV container and the top-level UL. The MenuLink class renders all LI elements, including the child A element. The AMenuSub renders the UL element for the sub-menus.

The picture bellow shows the final DOM tree. The screenshot was taken from the included demo application running on Firefox.

Image 2

Internet Explorer 6

Since IE6 doesn't support CSS2, the CSS child selectors used to show the sub-menus won't work. The workaround was to wrap each sub-menu in a TABLE, and making it a child element of the A element (instead of the LI element). This is done by generating conditional comments for each A element. I'm not sure who to credit for this clever solution, I first saw it in the work done by Stu Nicholls (http://www.cssplay.co.uk).

The picture bellow shows the DOM tree as rendered on IE6

Image 3

Using the Code

The menu components expose the following public properties:

AMenu:

ArrowImage
URL of the arrow image. Should be 10x10. Default: none
BackColor
Menu background color. Default: #F7F7F7
BackHover
Hover background color. Default: #DAE0E4
BorderColor
Border color. Default: #C6C6CC
Font-Bold
Use bold font? Default: false.
Font-Names
Menu font names. Default: Arial.
Font-Size
Menu font size. Default: 12px.
ForeColor
Menu foreground color. Default: #336666.
ForeHover
Hover foreground color. Default: Blue.
Border
Draw border for the top-menu? Default: false.
Height
Menu height. Default: 10em.
Width
Menu width. Default: 190px.
SubWidth
Default sub-menu width. Default: 190px.

AMenuSub:

Width
Sub-menu width. Default: none.

MenuLink:

Text
Text of the menu-item.
IconImage
URL of the icon image. Default: none.
CommandName
Item's CommandName parameter. Default: none.
CommandArgument
Item's CommandArgument parameter. Default: none.
PostBackUrl
URL of the page to post to. Default: none.
Enabled
Item enabled? Default: yes.
OnClientClick
Client-side handler. Default: none.
ToolTip
Tooltip text. Default: none.

Events:

The control provides two options for handling the selection events.

On the first level, the MenuLink component accepts an "OnClick" handler. If specified, this handler is called to process the selection, and the event is not bubbled further.

On the second (top) level the AMenu component accepts an "OnItemClick" handler. If specified, this handler is called to process selection from all MenuLinks that have no handler.

The signature of both handlers is the same as that of a LinkButton:
void OnItemClick(object sender, CommandEventArgs e);

Note: The handlers are only called if the CommandName parameter of the MenuLink has been specified. Generally, the usage of CommandName, CommandArgument, and PostBackUrl is the same as for a LinkButton.

The picture bellow shows the event argument parsed by the handler:

Image 4

Example

Following is the sample from the Introduction but this time using AMenu. Please make sure you've included a reference to the amenu.dll assembly, and the amenu.css stylesheet is accessible.

File test.aspx:

HTML
<%@ Page Language="C#"  CodeBehind="test.aspx.cs" Inherits="TestPage" %>
<%@ Register TagPrefix="mt" Namespace="mtweb" Assembly="AMenu" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">
  <title>AMenu test</title>
  <link href="amenu.css" type="text/css" rel="stylesheet" />
</head>

<body>
<form id="Form1" runat="server">

  <mt:AMenu ID="Menu3" runat="server" Border="true"  OnItemClick="OnItemClick">
    <mt:MenuLink ID="PartsCatalog" runat="server" Text="Parts Catalog ...">
      <mt:AMenuSub ID="SubParts" runat="server">
        <mt:MenuLink ID="Batteries" runat="server" Text="Batteries" />
        <mt:MenuLink ID="Alternators" runat="server" Text="Alternators" />
      </mt:AMenuSub>
    </mt:MenuLink>
  </mt:AMenu>
	
</form>
</body>
</html>

File test.aspx.cs:

C#
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class TestPage : System.Web.UI.Page
{
  protected void OnItemClick(object sender, CommandEventArgs e)
  {
    string from = ((Control)sender).ClientID;
    string cmd = e.CommandName;
    string arg = e.CommandArgument as string;
    // ...
  }
}

And the result:

Image 5

Limitations

There are several limitation, which may, or may not be an issue when you decide to use this control. In any case, by modifying the amenu.css style sheet, and the menu source code one should be able to adapt the control to a specific scenario.

Several properties are not exposed. E.g.: you can't change the default 1px border without modifying the amenu.css style sheet, and the methods in MenuLink.cs where the position of the sub-menus is calculated. The same for the left margin of the MenuLink text (the distance between the icon and the text), or the 2px padding around the menu items, or the 2em line height.

No support for the Visual Studio designer. Dragging the components from the toolbar will not work.

The markup generated is not "fluid". When a user configures her browser to force a specific font size (e.g.: "Minimum font size" in Firefox), the submenus will not be aligned correctly.

Conclusion

For most scenarios the control could be deployed just by changing the color schema and the icons. For specific needs, the source code should be a good starting point to implement your own.

The included demo application may be of interest to those who are just starting with .NET. It uses dynamically loaded user controls (ascx), update panels (including triggers and progress controls) history management, and more.

History

10/05/2009 - initial release.
10/07/2009 - fixed bug in handling PostBackUrl.
10/08/2009 - minor update to the demo application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Europe Europe
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 4 Pin
Muhammad Shahid Farooq5-Aug-12 2:40
professionalMuhammad Shahid Farooq5-Aug-12 2:40 
Good
GeneralProblem Pin
N3G4T1V37-Oct-09 8:47
N3G4T1V37-Oct-09 8:47 
GeneralRe: Problem PinPopular
tomi007-Oct-09 9:54
tomi007-Oct-09 9:54 
GeneralMy vote of 5 Pin
Joe Programm3r6-Oct-09 3:34
Joe Programm3r6-Oct-09 3:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.