Asp.net mvc 4 是否有一个简单的MVC4 html帮助程序用于可折叠(多级)引导3菜单?

Asp.net mvc 4 是否有一个简单的MVC4 html帮助程序用于可折叠(多级)引导3菜单?,asp.net-mvc-4,c#-4.0,twitter-bootstrap,view-helpers,Asp.net Mvc 4,C# 4.0,Twitter Bootstrap,View Helpers,我已经看到了为active菜单项创建HTML助手方法的示例 **摘要:*简单地说,在一个MVC项目中,使用Twitter引导,我试图在选择一个子菜单时保持可折叠菜单的打开状态 我使用的是一个可折叠菜单,如果选择了一个子项,则父项的css(所选项)需要包含活动打开。这将确保菜单在正确位置打开。使用另一个HTML帮助程序时,活动项已设置为active 用于菜单的HTML: <div id="sidebar"> <ul> <

我已经看到了为
active
菜单项创建HTML助手方法的示例

**摘要:*
简单地说,在一个MVC项目中,使用Twitter引导,我试图在选择一个子菜单时保持可折叠菜单的打开状态

我使用的是一个可折叠菜单,如果选择了一个子项,则父项的css(所选项)需要包含
活动打开
。这将确保菜单在正确位置打开。使用另一个HTML帮助程序时,活动项已设置为
active

用于菜单的HTML:

    <div id="sidebar">
        <ul>
            <li class="active"><a href="dashboard.html"><i class="icon-home"></i> <span>Dashboard</span></a></li>
            <li class="submenu">
                <a href="#"><i class="icon-beaker"></i> <span>UI Lab</span> <i class="arrow icon-chevron-right"></i></a>
                <ul>
                    <li><a href="interface.html">Interface Elements</a></li>
                    <li><a href="jquery-ui.html">jQuery UI</a></li>
                    <li><a href="buttons.html">Buttons &amp; icons</a></li>
                </ul>
            </li>
            <li class="submenu">
                <a href="#"><i class="icon-th-list"></i> <span>Form elements</span> <i class="arrow icon-chevron-right"></i></a>
                <ul>
                    <li><a href="form-common.html">Common elements</a></li>
                    <li><a href="form-validation.html">Validation</a></li>
                    <li><a href="form-wizard.html">Wizard</a></li>
                </ul>
            </li>
            <li><a href="tables.html"><i class="icon-th"></i> <span>Tables</span></a></li>
            <li><a href="grid.html"><i class="icon-th-list"></i> <span>Grid Layout</span></a></li>
            <li class="submenu">
                <a href="#"><i class="icon-file"></i> <span>Sample pages</span> <i class="arrow icon-chevron-right"></i></a>
                <ul>
                    <li><a href="invoice.html">Invoice</a></li>
                    <li><a href="chat.html">Support chat</a></li>
                    <li><a href="calendar.html">Calendar</a></li>
                    <li><a href="gallery.html">Gallery</a></li>
                    <li><a href="messages.html">Messages</a></li>
                </ul>
            </li>
            <li>
                <a href="charts.html"><i class="icon-signal"></i> <span>Charts &amp; graphs</span></a>
            </li>
            <li>
                <a href="widgets.html"><i class="icon-inbox"></i> <span>Widgets</span></a>
            </li>
        </ul>

    </div>

以下是项目的帮助器方法:

    public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper,
        string text,
        string action,
        string controller,
        string iconClass)
    {
        var li = new TagBuilder("li");
        var routeData = htmlHelper.ViewContext.RouteData;
        var currentAction = routeData.GetRequiredString("action");
        var currentController = routeData.GetRequiredString("controller");
        if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase))
        {
            li.AddCssClass("active");
        }

        var i = new TagBuilder("i");
        i.AddCssClass(iconClass);

        var basePath = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);

        //li.InnerHtml = htmlHelper.ActionLink("<i>something</i>" + text, action, controller).ToHtmlString();
        li.InnerHtml = htmlHelper.Raw(string.Format("<a href=\"{0}/{1}/{2}\"><i class=\"{4}\"></i>{3}</a>", basePath, controller, action, text, iconClass)).ToString();

        return MvcHtmlString.Create(li.ToString());
    }
公共静态MvcHtmlString菜单项(此HtmlHelper HtmlHelper,
字符串文本,
弦作用,
字符串控制器,
字符串(图标类)
{
var li=新标记生成器(“li”);
var routeData=htmlHelper.ViewContext.routeData;
var currentAction=RoutedData.GetRequiredString(“操作”);
var currentController=RoutedData.GetRequiredString(“控制器”);
if(string.Equals(currentAction、action、StringComparison.OrdinalIgnoreCase)&&
string.Equals(currentController、controller、StringComparison.OrdinalIgnoreCase))
{
li.添加CSSClass(“活动”);
}
var i=新标记生成器(“i”);
i、 AddCssClass(iconClass);
var basePath=HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
//li.InnerHtml=htmlHelper.ActionLink(“某物”+文本、动作、控制器).ToHtmlString();
li.InnerHtml=htmlHelper.Raw(string.Format(“”,basePath,controller,action,text,iconClass)).ToString();
返回MvcHtmlString.Create(li.ToString());
}
并实施如下:

        <div id="sidebar">
            <ul>
                @Html.MenuItem("Dashboard", "Index", "Dashboard", "icon-home")
@*              <li class="active"><a href="dashboard.html"><i class="icon-home"></i> <span>Dashboard</span></a></li>*@
                <li class="submenu">
                    <a href="#"><i class="icon-beaker"></i> <span>UI Lab</span> <i class="arrow icon-chevron-right"></i></a>

                    <ul>
                        <li>@Html.MenuItem("Websites", "Index", "Websites", null)</li>
                        <li><a href="jquery-ui.html">jQuery UI</a></li>
                        <li><a href="buttons.html">Buttons &amp; icons</a></li>
                    </ul>
                </li>
                <li class="submenu">
                    <a href="#"><i class="icon-th-list"></i> <span>Form elements</span> <i class="arrow icon-chevron-right"></i></a>
                    <ul>
                        <li><a href="form-common.html">Common elements</a></li>
                        <li><a href="form-validation.html">Validation</a></li>
                        <li><a href="form-wizard.html">Wizard</a></li>
                    </ul>
                </li>

    @菜单项(“仪表板”、“索引”、“仪表板”、“图标主页”) @*
  • *@
    • @Html.MenuItem(“网站”、“索引”、“网站”,null)
所以我没有子菜单项的东西

有没有更简单的方法来实现这一点

--更新--


我想,把这个放在局部视图中可能是最好的。我需要找到一些方法在单击时保留所选项目,以在每个菜单项上引用它,而不是检查控制器/操作是否匹配,以便将当前项目设置为“活动”。单击时激活的控制器方法,检查当前选定的项是父项还是子项,以及父项是否与子项匹配,然后使用不同的格式?我相信一定会有更简单的方法。

好的,这里是我想出的一个解决方案

总而言之,这并不像在选中某个项目时向其添加“活动”CSS类那样简单(根据默认的引导MVC)。在这个解决方案中,我们需要识别父项和子项,并同时识别两者

默认页面是Dashboard。然后用户单击“配置”展开菜单,然后选择打开页面的“网站”链接

以下是解决方案:

型号:

public class NavigationMenu
{
    public string Text { get; set; }
    public string Action { get; set; }
    public string Controller { get; set; }
    public string Icon { get; set; }
    public bool Selected { get; set; }

    public List<NavigationMenu> MenuChildren;
}
public class MenuViewModel
{
    public IList<MenuItemDto> MenuItems; 
}

public class MenuItemDto
{
    public string Text { get; set; }
    public string Action { get; set; }
    public string Controller { get; set; }
    public string IconCssClass { get; set; }
    public bool Active { get; set; }

    public List<MenuItemDto> MenuChildren;
}
控制器检查当前操作/控制器名称是否与菜单上的名称匹配,如果匹配,则设置
selected=true
。在局部视图中,有一些逻辑根据父/子关系确定显示结构,如果选择了子对象,则父对象也是如此


简而言之,就是这样。我想听听一些评论/其他示例。

这里是一个解决方案,使用了来自的大部分代码,经过重构,使用了HtmlHelpers和标记生成器,并进行了一些重命名,以适合我的项目

型号:

public class NavigationMenu
{
    public string Text { get; set; }
    public string Action { get; set; }
    public string Controller { get; set; }
    public string Icon { get; set; }
    public bool Selected { get; set; }

    public List<NavigationMenu> MenuChildren;
}
public class MenuViewModel
{
    public IList<MenuItemDto> MenuItems; 
}

public class MenuItemDto
{
    public string Text { get; set; }
    public string Action { get; set; }
    public string Controller { get; set; }
    public string IconCssClass { get; set; }
    public bool Active { get; set; }

    public List<MenuItemDto> MenuChildren;
}
共享视图:

@model IEnumerable<AdminWebsite.Models.NavigationMenu>
@{
    var basePath = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}
<div id="sidebar">
    @Html.Raw("<ul>")
        @foreach (var item in Model)
        {
            // if the menu item does not have children then it should be clickable
            if (item.MenuChildren == null & item.Selected)
            {
                <li class="active"><a href="@String.Format("{0}/{1}/{2}", basePath, item.Controller, item.Action)"><i class="@item.Icon"></i> <span>@item.Text</span></a></li>
            }
            else if (item.MenuChildren == null & !item.Selected)
            {
                <li><a href="@String.Format("{0}/{1}/{2}", basePath, item.Controller, item.Action)"><i class="@item.Icon"></i> <span>@item.Text</span></a></li>
            }

            // has children and one of its children is selected
            if (item.MenuChildren != null)
            {
                if (item.MenuChildren.Any(c => c.Selected) == true)
                {                
                    <text><li class="submenu active open"></text>
                }
                else
                {
                    <text><li class="submenu"></text>
                }

                // sub-menu parent
                if (item.MenuChildren != null & item.Selected)
                {
                    <a href="@String.Format("{0}/{1}/{2}", basePath, item.Action, item.Controller)"><i class="@item.Icon"></i> <span>@item.Text</span></a>
                }
                else if (item.MenuChildren != null & !item.Selected)
                {
                    <a href="@String.Format("{0}/{1}/{2}", basePath, item.Action, item.Controller)"><i class="@item.Icon"></i> <span>@item.Text</span></a>
                }

                // children
                <text><ul></text>
                    // iterate through children
                    foreach(var cItem in item.MenuChildren)
                    {
                        if (cItem.MenuChildren == null & cItem.Selected)
                        {
                            <li class="active"><a href="@String.Format("{0}/{1}/{2}", basePath, cItem.Controller, cItem.Action)"><i class="@cItem.Icon"></i> <span>@cItem.Text</span></a></li>
                        }
                        else if (cItem.MenuChildren == null & !cItem.Selected)
                        {
                            <li><a href="@String.Format("{0}/{1}/{2}", basePath, cItem.Controller, cItem.Action)"><i class="@cItem.Icon"></i> <span>@cItem.Text</span></a></li>
                        }                    
                    }

                @Html.Raw("</ul>");


                @Html.Raw("</li>");
            }

        }
    @Html.Raw("</ul>")
</div>
@using Extensions

<div id="sidebar">
    @Html.Raw("<ul>")

    @foreach (var item in Model.MenuItems)
    {
        // if the menu item does not have     children then it should be clickable
        if (item.MenuChildren == null)
        {
            @Html.LiForMenuItem(item)
        }

        // has children and one of its children     is selected
        if (item.MenuChildren != null)
        {
            if (item.MenuChildren.Any(c => c.    Active) == true)
            {
                <text><li class="submenu active     open">
                </text>
            }
            else
            {
                <text>
                <li class="submenu">
                </text>
            }

            // sub-menu parent
            if (item.MenuChildren != null)
            {
                @Html.HrefForSubMenuItemRoot(    item)
            }

            // children
            <text><ul>
            </text>
            // iterate through children
            foreach (var cItem in item.    MenuChildren)
            {
                if (cItem.MenuChildren == null)
                {
                    @Html.LiForMenuItem(cItem)
                }
            }
            @Html.Raw("</ul>");

        @Html.Raw("</li>");
        }

    }
    @Html.Raw("</ul>")
</div>
使用扩展名 @Html.Raw(“
    ”) @foreach(Model.MenuItems中的var项) { //如果菜单项没有子项,则应可单击 if(item.MenuChildren==null) { @Html.LiForMenuItem(item) } //具有子项,并且选择了其中一个子项 如果(item.MenuChildren!=null) { if(item.MenuChildren.Any(c=>c.Active)==true) {
  • } 其他的 {
  • } //子菜单父菜单 如果(item.MenuChildren!=null) { @Html.HrefForSubMenuItemRoot(项目) } //孩子们
      @using Extensions
      
      <div id="sidebar">
          @Html.Raw("<ul>")
      
          @foreach (var item in Model.MenuItems)
          {
              // if the menu item does not have     children then it should be clickable
              if (item.MenuChildren == null)
              {
                  @Html.LiForMenuItem(item)
              }
      
              // has children and one of its children     is selected
              if (item.MenuChildren != null)
              {
                  if (item.MenuChildren.Any(c => c.    Active) == true)
                  {
                      <text><li class="submenu active     open">
                      </text>
                  }
                  else
                  {
                      <text>
                      <li class="submenu">
                      </text>
                  }
      
                  // sub-menu parent
                  if (item.MenuChildren != null)
                  {
                      @Html.HrefForSubMenuItemRoot(    item)
                  }
      
                  // children
                  <text><ul>
                  </text>
                  // iterate through children
                  foreach (var cItem in item.    MenuChildren)
                  {
                      if (cItem.MenuChildren == null)
                      {
                          @Html.LiForMenuItem(cItem)
                      }
                  }
                  @Html.Raw("</ul>");
      
              @Html.Raw("</li>");
              }
      
          }
          @Html.Raw("</ul>")
      </div>
      
      namespace Extensions
      {
          public static class MenuExtensions
          {
              public static MvcHtmlString LiForMenuItem(this HtmlHelper htmlHelper, MenuItemDto menuItem)
              {
                  var li = new TagBuilder("li");
                  AddActiveCssClassToTag(menuItem, li);
                  var contentUrl = GenerateContentUrlFromHttpContext(htmlHelper);
                  li.InnerHtml = GenerateLinkForMenuItem(menuItem, contentUrl);
                  return MvcHtmlString.Create(li.ToString());
              }
      
              public static MvcHtmlString HrefForSubMenuItemRoot(this HtmlHelper htmlHelper, MenuItemDto menuItem)
              {
                  var a = new TagBuilder("a");
                  AddActiveCssClassToTag(menuItem, a);
                  var contentUrl = GenerateContentUrlFromHttpContext(htmlHelper);
                  a.Attributes.Add("href", GenerateUrlForMenuItem(menuItem, contentUrl));
                  a.InnerHtml = GenerateInnerHtmlForMenuItem(menuItem);
                  return MvcHtmlString.Create(a.ToString());
              }
      
              private static void AddActiveCssClassToTag(MenuItemDto menuItem, TagBuilder tag)
              {
                  if (menuItem.Active)
                  {
                      tag.AddCssClass("active");
                  }
              }
      
              private static string GenerateContentUrlFromHttpContext(HtmlHelper htmlHelper)
              {
                  return UrlHelper.GenerateContentUrl("~/", htmlHelper.ViewContext.HttpContext);
              }
      
              private static string GenerateLinkForMenuItem(MenuItemDto menuItem, string contentUrl)
              {
                  var a = new TagBuilder("a");
                  a.Attributes.Add("href", GenerateUrlForMenuItem(menuItem, contentUrl));
                  a.InnerHtml = GenerateInnerHtmlForMenuItem(menuItem);
                  return a.ToString();
              }
      
              private static string GenerateInnerHtmlForMenuItem(MenuItemDto menuItem)
              {
                  var html = string.Empty;
      
                  //Add <i></i> if there is an IconCssClass present
                  var i = new TagBuilder("i");
                  if (!String.IsNullOrEmpty(menuItem.IconCssClass))
                  {
                      i.AddCssClass(menuItem.IconCssClass);
                      html += i.ToString();
                  }
      
                  //add a span for the text of the menuItem
                  var span = new TagBuilder("span");
                  span.InnerHtml = menuItem.Text;
      
                  html += span.ToString();
      
                  return html;
              }
      
              private static string GenerateUrlForMenuItem(MenuItemDto menuItem, string contentUrl)
              {
                  var url = contentUrl + menuItem.Controller;
                  if (!String.IsNullOrEmpty(menuItem.Action)) url += "/" + menuItem.Action;
                  return url;
              }
          }
      }