65.9K
CodeProject 正在变化。 阅读更多。
Home

AMenu - 一个简单的 .NET 垂直菜单

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (22投票s)

2009年10月5日

CPOL

4分钟阅读

viewsIcon

65303

downloadIcon

3081

一个基于 CSS 的 .NET 垂直菜单控件。

AMenu screenshot

引言

AMenu 是一个简单的 .Net 包装器,用于一个基于 CSS 的“弹出式”垂直菜单。网上有很多关于 CSS 菜单工作原理的优秀文章,例如:http://www.seoconsultants.com/css/menus/tutorial。基本上,菜单是使用嵌套的 UL 元素实现的,其中每个 LI 都包含一个超链接。

CSS 的主要功能是隐藏/显示子菜单,并实现所需的布局。隐藏是通过在 UL 元素上使用 {disaply:none} 或将元素移出屏幕 {left:-5000px} 来完成的。子菜单是通过在 hover 伪类 中使用 子选择器 指定其位置来显示的:li:hover > ul {left:100%}.

以下是一个演示该概念的工作示例。请注意,为了清晰起见,已省略 IE6 特定的代码;此示例在除 IE6 之外的所有浏览器上都可以正常工作。

文件 test.htm

<!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> 

实现

菜单实现为三个 WebControl 派生组件:AMenu、AMenuSub、MenuLink 和关联的样式表 amenu.css。

AMenu 类负责渲染 DIV 容器和顶级 UL。MenuLink 类渲染所有 LI 元素,包括子 A 元素。AMenuSub 渲染子菜单的 UL 元素。

下面的图片显示了最终的 DOM 树。屏幕截图是从包含的演示应用程序在 Firefox 上运行时截取的。

Internet Explorer 6

由于 IE6 不支持 CSS2,用于显示子菜单的 CSS 子选择器将不起作用。解决方法是将每个子菜单包装在 TABLE 中,并使其成为 A 元素(而不是 LI 元素)的子元素。这是通过为每个 A 元素生成条件注释来实现的。我不确定该巧妙解决方案应归功于谁,我最初是在 Stu Nicholls (http://www.cssplay.co.uk) 的工作中看到的。

下面的图片显示了在 IE6 上渲染的 DOM 树

Using the Code

菜单组件公开以下公共属性

AMenu

ArrowImage
箭头图像的 URL。应为 10x10。默认值:无
BackColor
菜单背景色。默认值:#F7F7F7
BackHover
悬停背景色。默认值:#DAE0E4
BorderColor
边框颜色。默认值:#C6C6CC
Font-Bold
使用粗体字体?默认值:false。
Font-Names
菜单字体名称。默认值:Arial。
Font-Size
菜单字体大小。默认值:12px。
ForeColor
菜单前景色。默认值:#336666。
ForeHover
悬停前景色。默认值:蓝色。
Border
为顶部菜单绘制边框?默认值:false。
高度
菜单高度。默认值:10em。
宽度
菜单宽度。默认值:190px。
SubWidth
默认子菜单宽度。默认值:190px。

AMenuSub

宽度
子菜单宽度。默认值:无。

MenuLink

文本
菜单项的文本。
IconImage
图标图像的 URL。默认值:无。
CommandName
项的 CommandName 参数。默认值:无。
CommandArgument
项的 CommandArgument 参数。默认值:无。
PostBackUrl
提交到的页面的 URL。默认值:无。
Enabled
项是否启用?默认值:是。
OnClientClick
客户端处理程序。默认值:无。
工具提示
Tooltip 文本。默认值:无。

事件

该控件提供了两种处理选择事件的选项。

第一级,MenuLink 组件接受一个“OnClick”处理程序。如果指定,将调用此处理程序来处理选择,并且事件不会进一步冒泡。

在第二(顶部)级,AMenu 组件接受一个“OnItemClick”处理程序。如果指定,将调用此处理程序来处理来自所有没有处理程序的 MenuLink 的选择。

两个处理程序的签名与 LinkButton 相同
void OnItemClick(object sender, CommandEventArgs e);

注意:仅当指定了 MenuLink 的 CommandName 参数时,才会调用处理程序。通常,CommandName、CommandArgument 和 PostBackUrl 的用法与 LinkButton 相同。

下面的图片显示了处理程序解析的事件参数

示例

以下是导言中的示例,但这次使用 AMenu。请确保您已包含对 amenu.dll 程序集的引用,并且 amenu.css 样式表可访问。

文件 test.aspx

<%@ 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>

文件 test.aspx.cs

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;
    // ...
  }
}

结果

限制

存在几项限制,您在使用此控件时可能会或可能不会遇到问题。无论如何,通过修改 amenu.css 样式表和菜单源代码,应该能够将控件适应特定场景。

未公开几个属性。例如:您无法更改默认的 1px 边框而不修改 amenu.css 样式表以及 MenuLink.cs 中计算子菜单位置的方法。对于 MenuLink 文本的左边距(图标和文本之间的距离),或菜单项周围的 2px 填充,或 2em 的行高,也是如此。

不支持 Visual Studio 设计器。从工具栏拖动组件将不起作用。

生成的标记不是“流动的”。当用户配置其浏览器以强制使用特定的字体大小时(例如,Firefox 中的“最小字体大小”),子菜单将无法正确对齐。

结论

在大多数情况下,只需更改颜色方案和图标即可部署该控件。对于特定需求,源代码可以作为实现您自己的良好起点。

包含的演示应用程序可能对那些刚开始接触 .NET 的人感兴趣。它使用动态加载的用户控件 (ascx)、更新面板(包括触发器和进度控件)、历史记录管理等等。

历史

2009/10/05 - 首次发布。
2009/10/07 - 修复了处理 PostBackUrl 的错误。
2009/10/08 - 对演示应用程序进行了小更新。

© . All rights reserved.