2013-11-22 35 views
6

我想标记当前节点,它是父类的一个css类。我在寻找了一圈,发现这些链接:MVCSitemapProvider指示当前节点和父节点

http://mvcsitemap.codeplex.com/discussions/257786 http://mvcsitemap.codeplex.com/discussions/245000

所以我修改SiteMapNodeModelList.cshtml现在,当前节点正在凸显。但不知道如何突出显示父节点。

<ul> 
    @foreach (var node in Model) { 
     <li class="@(node.IsCurrentNode ? "current" : "")" >@Html.DisplayFor(m => node) 
      @if (node.Children.Any()) { 
       @Html.DisplayFor(m => node.Children) 
      } 
     </li> 
    } 
</ul> 

为了纪念我建立的一个检查所有直接子元素的扩展方法父节点(我只有2级):

public static bool IsCurrentNodeOrChild(this SiteMapNodeModel node) 
    { 
     if (node.IsCurrentNode) return true; 

     return node.Children.Any(n => n.IsCurrentNode); 
    } 

而改变MenuHelperModel.cshtml这样的:

<ul id="menu"> 
    @foreach (var node in Model.Nodes) { 
     <li class="@(node.IsCurrentNodeOrChild() ? "current" : "d")" >@Html.DisplayFor(m => node) 
      @if (node.Children.Any()) { 
       @Html.DisplayFor(m => node.Children) 
      } 
     </li> 
    } 
</ul> 

这现在完美。但是真的没有简单的方法吗?不能成为地球上第一个需要这个的人吗?

回答

3

你很可能是地球上第一个需要它的人。然后再次,我怀疑有几十个有用的方法库可以使MvcSiteMapProvider更有用。

MvcSiteMapProvider是一个开源协作工作。如果你发现这样的东西可能对很多人有用,请通过pull request @GitHub on the dev branch来欣赏making a contribution。这个想法会做出非常好的贡献。我建议直接将该方法添加到SiteMapNodeModel对象。

+1

谢谢!这不是针对MvcSiteMapProvider的。我越来越觉得我在某个地方失去了某种东西。 – Remy

+1

我创建了一个git pull。 https://github.com/maartenba/MvcSiteMapProvider/pull/251 我希望我已经做到了这一点。 – Remy

+0

对不起,为了让它恢复原状,但有没有可能通过自定义标签扩展SiteMapNodeModel(例如,用于过滤节点)?我想使用node.ResourceKey,但节点无法访问。 – Storm

5

也就是说真的很酷,但是当我不断创造这样那样的扩展,我采取了不同的做法,但我要指出,这是根据你的想法:d

MainMenu.cshtml:

@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel 
@using MvcSiteMapProvider.Web.Html.Models 

@foreach (var node in Model.Nodes) 
{ 
    <li @((node.IsCurrentNode || node.Children.Any(n => n.IsCurrentNode)) ? "class=active" : "")>@Html.DisplayFor(m => node)</li> 
} 

,并插入到这个

_Layout.cshtml

@Html.MvcSiteMap().Menu("MainMenu") 

基本上它做同样的事情,只是一点点清洁(在我看来)

0

这是一个伟大的发布!

虽然我不同意来自另一张海报的评论,但这个页面正是我所期待的。我的顾客正在用子菜单的子菜单在大菜单中迷路......虽然我不是它的粉丝,但这正是他们想要的。

我想改进Theodor的建议。而不是使用node.Children,请使用node.Descendants。这样,如果你在第二个子列表中,它仍然显示在顶部!

@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel 
@using System.Web.Mvc.Html 
@using MvcSiteMapProvider.Web.Html.Models 

@helper TopMenu(List<SiteMapNodeModel> nodeList) 
{ 
    <nav class="navbar navbar-default" role="navigation"> 
     <div class="container-fluid"> 
      <div class="collapse navbar-collapse"> 
       <ul class="nav navbar-nav"> 
        @foreach (SiteMapNodeModel node in nodeList) 
        { 
         string url = node.IsClickable ? node.Url : "#"; 

         if (!node.Children.Any()) 
         { 
          <li class="@((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "")"><a href="@url">@node.Title</a></li> 
         } 
         else 
         { 
          <li class="dropdown @((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "")"><a class="dropdown-toggle" data-toggle="dropdown">@node.Title <span class="caret"></span></a>@DropDownMenu(node.Children)</li> 
         } 

         if (node != nodeList.Last()) 
         { 
          <li class="divider-vertical"></li> 
         } 
        } 
       </ul> 
      </div> 
     </div> 
    </nav> 
} 

@helper DropDownMenu(SiteMapNodeModelList nodeList) 
{ 
    <ul class="dropdown-menu" role="menu"> 
     @foreach (SiteMapNodeModel node in nodeList) 
     { 
      if (node.Title == "Separator") 
      { 
       <li class="divider"></li> 
       continue; 
      } 

      string url = node.IsClickable ? node.Url : "#"; 

      if (!node.Children.Any()) 
      { 
       <li class="@((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "d")"><a href="@url">@node.Title</a></li> 
      } 
      else 
      { 
       <li class="dropdown-submenu @((node.IsCurrentNode || node.Descendants.Any(n => n.IsCurrentNode)) ? "active" : "d")"><a href="@url">@node.Title</a>@DropDownMenu(node.Children)</li> 
      } 
     } 
    </ul> 
} 

@TopMenu(Model.Nodes) 
相关问题