zoukankan      html  css  js  c++  java
  • [ASP.NET MVC]利用ASP.NET SiteMap生成与Bootstrap“兼容”菜单

    Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。它由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架。本文提供了一个解决方案利用ASP.NET SiteMap生成与Bootstrap“兼容”的菜单。具体的原理很简单,就是利用SiteMap读取预先定义的网站结构,按照Bootstrap的标准生成相应的HTML。[源代码从这里下载]

    我们将基于菜单的呈现定义在HtmlHelper的扩展方法中。如下面的代码片断,扩展方法RenderBootstrapMenu具有一个缺省的参数siteMapProviderName ,表示读取SiteMap结构采用的SiteMapProvider的配置名称。在该方法中,我们通过指定的SiteMapProvider(如果没有指定,则采用默认配置的SiteMapProvider)得到代表整个SiteMap根节点的SiteMapNode对象,并将其子节点(以及子节点的子节点,…)转换成相应的HTML。

       1: public static class BootstrapMenuExtensions
       2: {        
       3:     public static MvcHtmlString RenderBootstrapMenu(this HtmlHelper helper, string siteMapProviderName = "")
       4:     {
       5:         SiteMapProvider siteMapProvider = !string.IsNullOrEmpty(siteMapProviderName) ?
       6:             SiteMap.Providers[siteMapProviderName] :
       7:             SiteMap.Provider ?? SiteMap.Providers.Cast<SiteMapProvider>().First();
       8:         return new MvcHtmlString( RenderMenu(siteMapProvider.RootNode.ChildNodes));
       9:     }
      10:  
      11:     private static string RenderMenu(SiteMapNodeCollection siteMapNodes)
      12:     {
      13:         TagBuilder ul = new TagBuilder("ul");
      14:         ul.AddCssClass("nav");
      15:         ul.AddCssClass("nav-pills");
      16:  
      17:         foreach (SiteMapNode node in siteMapNodes)
      18:         {
      19:             ul.InnerHtml += GetMenuItemHtml(node);
      20:         }
      21:         return ul.ToString();
      22:     }
      23:  
      24:     private static string GetMenuItemHtml(SiteMapNode siteMapNode)
      25:     {
      26:         TagBuilder li = new TagBuilder("li");
      27:         li.AddCssClass("dropdown");
      28:  
      29:         TagBuilder link = new TagBuilder("a");
      30:         link.Attributes.Add("href", siteMapNode.Url);
      31:         link.Attributes.Add("title", siteMapNode.Description);
      32:         link.SetInnerText(siteMapNode.Title);
      33:  
      34:         if (!siteMapNode.HasChildNodes)
      35:         {
      36:             li.InnerHtml += link.ToString();
      37:             return li.ToString();
      38:         }
      39:  
      40:         link.AddCssClass("dropdown-toggle");
      41:         link.Attributes.Add("data-toggle", "dropdown");
      42:         TagBuilder caret = new TagBuilder("b");
      43:         caret.AddCssClass("caret");
      44:         link.InnerHtml += caret.ToString();
      45:  
      46:         TagBuilder ul = new TagBuilder("ul");
      47:         ul.AddCssClass("dropdown-menu");
      48:         foreach (SiteMapNode node in siteMapNode.ChildNodes)
      49:         {
      50:             ul.InnerHtml += GetSubItemHtml(node);
      51:         }
      52:         li.InnerHtml += link.ToString();
      53:         li.InnerHtml += ul.ToString();
      54:         return li.ToString();
      55:     }
      56:  
      57:     private static string GetSubItemHtml(SiteMapNode siteMapNode)
      58:     {
      59:         TagBuilder li = new TagBuilder("li");
      60:  
      61:         TagBuilder link = new TagBuilder("a");
      62:         link.Attributes.Add("href", siteMapNode.Url);
      63:         link.Attributes.Add("title", siteMapNode.Description);
      64:         link.SetInnerText(siteMapNode.Title);
      65:         li.InnerHtml += link.ToString();
      66:  
      67:         if (siteMapNode.HasChildNodes)
      68:         {
      69:             link.AddCssClass("dropdown-toggle");
      70:             link.Attributes.Add("data-toggle", "dropdown");
      71:  
      72:             li.AddCssClass("dropdown-submenu");
      73:             TagBuilder ul = new TagBuilder("ul");
      74:             ul.AddCssClass("dropdown-menu");
      75:             foreach (SiteMapNode node in siteMapNode.ChildNodes)
      76:             {
      77:                 ul.InnerHtml += GetSubItemHtml(node);
      78:             }
      79:             li.InnerHtml += ul.ToString();
      80:         }
      81:         return li.ToString();
      82:     }
      83: }

    假设我们采用XmlSiteMapProvider,SiteMap结构通过如下的XML来定义,整个结构具有三个层次。

       1: <?xml version="1.0" encoding="utf-8" ?>
       2: <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
       3:   <siteMapNode url="Root" title="Root"  description="">
       4:     <siteMapNode url="A1" title="A1"  description="1st Level 1" />
       5:     <siteMapNode url="A2" title="A2"  description="1st Level 2" />
       6:     <siteMapNode url="A3" title="A3"  description="1st Level 3">
       7:       <siteMapNode url="B1" title="B1"  description="2nd Level 1" />
       8:       <siteMapNode url="B2" title="B2"  description="2nd Level 2" />
       9:       <siteMapNode url="B3" title="B3"  description="2nd Level 3">
      10:         <siteMapNode url="C1" title="C1"  description="3rd Level 1" />
      11:         <siteMapNode url="C2" title="C2"  description="3rd Level 2" />
      12:         <siteMapNode url="C3" title="C3"  description="3rd Level 3" />
      13:       </siteMapNode>
      14:     </siteMapNode>
      15:   </siteMapNode>
      16: </siteMap>

    在如下一个View中,我们调用扩展方法RenderBootstrapMenu将由上面这个XML定义的菜单节点呈现出来。

       1: <!DOCTYPE html>
       2: <html>
       3: <head>
       4:     <title>Bootstrap Menu</title>
       5:     <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" />    
       6: </head>
       7: <body>
       8:     <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
       9:     <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
      10:     <div>
      11:         @Html.RenderBootstrapMenu()
      12:     </div>
      13: </body>
      14: </html>

    最终呈现的效果如下所示:

    image

    菜单对应的HTML为:

       1: <ul class="nav-pills nav">
       2:     <li class="dropdown"><a href="/A1" title="1st Level 1">A1</a></li>
       3:     <li class="dropdown"><a href="/A2" title="1st Level 2">A2</a></li>
       4:     <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="/A3" title="1st Level 3">A3<b class="caret"></b></a>
       5:         <ul class="dropdown-menu">
       6:             <li><a href="/B1" title="2nd Level 1">B1</a></li>
       7:             <li><a href="/B2" title="2nd Level 2">B2</a></li>
       8:             <li class="dropdown-submenu"><a href="/B3" title="2nd Level 3">B3</a>
       9:                   <ul class="dropdown-menu">
      10:     <li><a href="/C1" title="3rd Level 1">C1</a></li>
      11:                        <li><a href="/C2" title="3rd Level 2">C2</a></li>
      12:                        <li><a href="/C3" title="3rd Level 3">C3</a></li>
      13:                   </ul>
      14:             </li>
      15:         </ul>
      16:     </li>
      17: </ul>
    作者:Artech
    出处:http://artech.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    [Linux 流量管理] Cacti的插件安装和使用
    expdp impdp 数据库导入导出命令详解
    Dropping all user tables/sequences in Oracle
    Oracle RMAN 的 show,list,crosscheck,delete命令整理
    EXP00041错误,遇到字符集问题的解决方式
    ORA00312的解决方法
    如何禁止MSN传递文件
    如何解决Parallel query大于1的问题
    bzoj5028小Z的加油店(线段树+差分)
    [转]C# 互操作性入门系列(三):平台调用中的数据封送处理
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2726790.html
Copyright © 2011-2022 走看看