使用 CSS 友好菜单控件适配器在 C# 中实现带水平子菜单的水平菜单






4.81/5 (51投票s)
通过使用 C# 在 .NET 中从头开始利用 CSS Friendly Menu Adapter 的 ASP.NET 菜单控件呈现水平子菜单及水平菜单
此解决方案解决了什么问题?
通过内置的 ASP.NET 2.0 或 3.5 菜单控件呈现为 <table>
元素,这很难通过 CSS 和 JavaScript 进行管理。可以使用 CSS Menu Adapter Control 将菜单控件输出呈现为 <ul><li></ul>
HTML 元素而不是表格,这样更容易发出 100% 纯 CSS 的呈现输出。
换句话说,对于任何数据列表或在我们的例子中是菜单控件,如果您通过查看页面的源代码来注意 HTML 代码,ASP.NET
运行时引擎生成的内容,您可能会看到基于表格的布局,这当然很难设计,并且在新 Web 标准中不被认为是好的做法。 为了克服这个问题,CSS Control Adapter 是答案。 它将呈现 div
和无序列表 (UL
) 而不是 table
,这可以很容易地使用 CSS 重新设计。 这意味着您现在可以采用标准化方法来创建基于 Web 的控件。
通过本文,您可以使用 ASP.NET 菜单控件从头开始开发带有水平子菜单的水平菜单。
这对其他人有什么帮助?
通过本文,可以将 CSS Control Adapter 与 Menu Control 集成。 控制适配器可以帮助生成 CSS 友好的 HTML,而不会牺牲原始 Menu 控件的强大功能和灵活性。 例如,菜单的根节点(主菜单)可以垂直或水平布局,子节点(子菜单)也可以水平或垂直布局。
背景
网上有一些关于通过 CSS Friendly Menu Adapter 呈现菜单的文章。 大多数是针对带有垂直子菜单的垂直菜单或带有垂直子菜单的水平菜单。 我的重点是带有水平子菜单的水平菜单。
呈现的菜单
代码片段中发生了什么?
我的源代码包含如下所示的解决方案摘要
代码实际上是如何工作的?
CSS Friendly Control Adapter 会覆盖 ASP.NET Web 控件生成的默认 HTML,以通过 CSS 提供更符合标准的呈现方式。
控制适配器是类(在我们的例子中是 MenuAdapter
类),它通过 System.Web.UI.Adapters.ControlAdapter
基类派生,并实现呈现方法,允许控制适配器完全自定义单个控件的标记的呈现方式。
您可以按原样使用这些控制适配器类来获得纯 CSS 友好的输出(无需更改代码),或者如果您想自定义渲染输出,您可以调整它们。
然后,通过将 * .browser * 文件添加到项目应用程序根目录正下方的 * /App_Browsers * 目录中,将 ControlAdapters
注册到 ASP.NET。一个 * .browser * 文件包含简单的标记,如下所示,允许您指定哪个控制适配器应该用于哪个控件。
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.Menu"
adapterType="CSSFriendly.MenuAdapter" />
</controlAdapters>
</browser>
<browser id="W3C_Validator" parentID="default">
<identification>
<userAgent match="^W3C_Validator" />
</identification>
<capabilities>
<capability name="browser" value="W3C Validator" />
<capability name="ecmaScriptVersion" value="1.2" />
<capability name="javascript" value="true" />
<capability name="supportsCss" value="true" />
<capability name="supportsCallback" value="true" />
<capability name="tables" value="true" />
<capability name="tagWriter" value="System.Web.UI.HtmlTextWriter" />
<capability name="w3cdomversion" value="1.0" />
</capabilities>
</browser>
</browsers>
如果需要,您可以为不同的浏览器自定义不同的控制适配器,或者只为“默认”定义它们,以便默认将它们应用于访问您的应用程序的所有浏览器。
完成此操作后,您就可以开始了 - 并且可以使用标准 CSS 样式表来自定义所有样式信息。
如何添加菜单项
如果想要通过在站点地图中添加新节点来添加包含一些子菜单项的菜单项,您应该只为新类 .AspNet-Menu-4-Left
、.AspNet-Menu-4-Center
、.AspNet-Menu-4-Right
设置菜单样式,并为 MenuStyle.css 中的新类 AspNet-SubMenu-3
设置子菜单样式。
/* AspNet-Menu-1 indicate its for root menu item 1,
AspNet-Menu-2 for root menu item 2 and so on */
/*Each root menu item has three parts Left, Center and Right */
.AspNet-Menu-1-Left { background:url(../Images/Menu/blueleft.png) no-repeat;
width:15px; float:left; height:31px;}
.AspNet-Menu-1-Center { background:url(../Images/Menu/bluemid.png) repeat-x;
width:146px; float:left; height:31px;}
.AspNet-Menu-1-Right { background:url(../Images/Menu/blueright.png) no-repeat;
width:15px; float:left; height:31px;}
.AspNet-Menu-2-Left { background:url(../Images/Menu/brownleft.png) no-repeat;
width:15px; float:left; height:31px;}
.AspNet-Menu-2-Center { background:url(../Images/Menu/brownmid.png) repeat-x;
width:146px; float:left; height:31px;}
.AspNet-Menu-2-Right { background:url(../Images/Menu/brownright.png) no-repeat;
width:15px; float:left; height:31px;}
.AspNet-Menu-3-Left { background:url(../Images/Menu/violetleft.png) no-repeat;
width:15px; float:left; height:31px;}
.AspNet-Menu-3-Center { background:url(../Images/Menu/violetmid.png) repeat-x;
width:146px; float:left; height:31px;}
.AspNet-Menu-3-Right { background:url(../Images/Menu/violetright.png) no-repeat;
width:15px; float:left; height:31px;}
/* AspNet-SubMenu-1 indicate its for submenu of 2nd menu ,
AspNet-Menu-2 for submenu of 3rd menu
AspNet-Menu-3 for submenu of 4th menu and so on */
.AspNet-SubMenu-1{ position:absolute;left:0px; background-color :#c5b26f;}
.AspNet-SubMenu-2 { position:absolute; left:0px; background-color:#b188df;}
这里 AspNet-SubMenu-1
表明它是针对第 2 个菜单的子菜单,而不是第 1 个菜单,因为第 1 个菜单这里没有子菜单项。
水平子菜单的关键 CSS
Menu.css 包含以下带有水平菜单的水平子菜单的关键 CSS。
/* -------------------------------------------------------------------------- */
/* When the Menu control's Orientation property is Horizontal the adapter
/* wraps the menu with DIV */
/* whose class is AspNet-Menu-Horizontal.
/* This allows us to force the top tier of the menu to layout */
/* horizontally, whereas all subsequent tiers of the menu lay out vertically. */
.AspNet-Menu-Horizontal ul.AspNet-Menu li
{
float: left;
}
.AspNet-Menu-Horizontal ul.AspNet-Menu li li
{
float: left;
}
渲染 <ul><li></ul> 元素
在 MenuAdapter.cs 中,BuildItems
方法负责基于菜单动态呈现 <ul><li></ul>
元素。
private void BuildItems(MenuItemCollection items, bool isRoot, HtmlTextWriter writer)
{
if (items.Count > 0)
{
writer.WriteLine();
writer.WriteBeginTag("ul");
if (isRoot)
{
writer.WriteAttribute("class", "AspNet-Menu");
}
else
{
writer.WriteAttribute("class", "AspNet-SubMenu-"+subMenuNo);
subMenuNo++;
}
//subMenuNo=1 means, this is 1st SubMenu,
//2 means this is 2nd Submenu and so on
writer.Write(HtmlTextWriter.TagRightChar);
writer.Indent++;
int rootItemNo = 1;
foreach (MenuItem item in items)
{
if(items.Contains(firstMenuItem))
// rootItemNo=1 means, this is 1st rootItemNo,
// 2 means this is 2nd rootItemNo, etc.
BuildItem(item, writer, true, rootItemNo);
else
//Here IsRootItem=false so no need rootItemNo
BuildItem(item, writer, false, 0);
rootItemNo++;
}
writer.Indent--;
writer.WriteLine();
writer.WriteEndTag("ul");
}
}
增强的 ASP.NET 4.0 菜单控件
ASP.NET 4.0 通过提供 “RenderingMode”
属性使 Web 开发人员的工作变得更容易。 在这里,我们可以指定 ASP.NET Menu control 的 RenderMode
,它定义了 HTML 渲染内容类型。 默认情况下,模式为 “List”
,这意味着控件将呈现为 ul/li
。
参见 Abhijit Jana 的技术博客 ASP.NET 4.0 中的 CSS Friendly Menu Control。