这是一个很好的方法来设置一个2级导航(两个菜单,每个级别一个)与突出显示包括面包屑使用MvcSiteMapProvide

本文关键字:一个 显示 MvcSiteMapProvide 面包 包括 两个 方法 很好 设置 2级 菜单 | 更新日期: 2023-09-27 18:06:20

我只是潜入MVC SiteMapProvider和摆弄它,所以这个问题更多的是关于设计而不是不能实现我想要的。我设置了一个简单的MVC4 Web应用程序,使用MvcSiteMapProvider 3.3.4。

我想要实现的是有一个2级网站导航;一个用于水平显示的顶层,另一个用于垂直显示的下层。子菜单必须只显示在当前选定节点层次结构之下的节点。此外,我希望在两个级别中都突出显示活动节点,因此实际选中的节点,如果它是子节点,我还希望突出显示父节点。

我实际上能够设置东西,所以结果看起来像我想要的,但我真的不喜欢它在代码中的样子,所以我在这里问的是这是否是一种合法的方式来做到这一点,或者如果有人可以启发我关于我目前缺少的最佳实践。

实现这一点所面临的障碍是:

1)我只想使用一个站点地图文件,并在对MvcSiteMap的不同调用中显示不同级别的站点地图。菜单功能(如上所述,第1级是水平的,第2级是垂直的,第0级是站点地图的根节点[我不想看到的])

2)我的第二个问题是,我有Home-Controller的Index-Action作为我的根节点,但也作为根节点的子节点,因为我想要额外的层次结构,把其他Home-Controller的动作。当然,这需要一些额外的配置来显示适当的breadcrumb,因为事实证明,这也使选中的"Home"节点更加难以突出显示。

考虑到这一点,我设置了以下站点地图:

(web。配置部分)

<siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
      <providers>
        <clear />
        <add name="MvcSiteMapProvider" type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" siteMapFile="~/Mvc.Sitemap" securityTrimmingEnabled="true" cacheDuration="5" enableLocalization="true" scanAssembliesForSiteMapNodes="true" includeAssembliesForScan="" excludeAssembliesForScan="" attributesToIgnore="visibility" nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" siteMapNodeVisibilityProvider="MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider" siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" />
      </providers>
</siteMap>

(Mvc.Sitemap)
<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0"
            xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0 MvcSiteMapSchema.xsd"
            enableLocalization="true">
  <mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="!SiteMapPathHelper,*">
      <mvcSiteMapNode title="HomeSub" controller="Home" action="Sub">
      </mvcSiteMapNode>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Menu1" controller="Menu1" action="Index">
      <mvcSiteMapNode title="Menu1Sub" controller="Menu1" action="Sub">
      </mvcSiteMapNode>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Menu2" controller="Menu2" action="Index">
      <mvcSiteMapNode title="Menu2Sub" controller="Menu2" action="Sub">
      </mvcSiteMapNode>
    </mvcSiteMapNode>
  </mvcSiteMapNode>
</mvcSiteMap>

(观点' ' DisplayTemplates ' MenuHelperModel.cshtml共享)

@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models
<ul id="menu">
    @{
        string firstUrl = null;
    }
    @foreach (var node in Model.Nodes) {
        string classes = node.IsCurrentNode | node.IsInCurrentPath | ( ((MvcSiteMapProvider.MvcSiteMapNode)SiteMap.CurrentNode).Action == node.Action && ((MvcSiteMapProvider.MvcSiteMapNode)SiteMap.CurrentNode).Controller == node.Controller )
            ? "current" : "";
        if (firstUrl == null)
        {
            firstUrl = node.Url;
        }
        else if (node.Url.Contains(firstUrl))
        {
            classes += " child";
        }
        <li class="@classes">@Html.DisplayFor(m => node) 
            @if (node.Children.Any()) {
                @Html.DisplayFor(m => node.Children)
            }
        </li>
    }
</ul>

我用这个

渲染主站点菜单
@Html.MvcSiteMap("MvcSiteMapProvider").Menu(0, true, false, 1)

我把它读成"给我从根节点开始到下一级的菜单;将根节点置于与其子节点相同的级别,但不要向我显示根节点"。我没有得到这个调用,因为我希望相同的结果返回,如果我设置startingNodeInChildLevel为假,并离开showStartingNode为假,但它不是吗?怎么写才能更容易理解呢?

我的子菜单像这样

@Html.MvcSiteMap("MvcSiteMapProvider").Menu(2, 1, true)

老实说,我也不是很理解这个调用,我只是在尝试MvcSiteMap的不同重载时偶然发现了它。菜单,它似乎做了我所需要的(减少显示的节点,只有那些在选定的父节点)。有人能解释一下它到底是做什么的吗?

添加面包屑

@Html.MvcSiteMap("MvcSiteMapProvider").SiteMapPath()

既然这似乎对我有用,为什么我还要费心发布这个?

这是对MvcSiteMap的调用。对于第一次读这篇文章的人(或者可能是第一次读:-))来说,菜单肯定会让人感到困惑。

我不喜欢当前解决方案的第二件事是Home-Controller的Index-Action-Node中的可见性设置;我把它放在那里,所以Home-Node不会在面包屑中出现两次,如果我选择了"HomeSub"-Link。

第三件事:是否有更好的方法来确定当前节点是否被选中(在非常具体的情况下,"Home"被选中,因为它也是"Home"的子节点)?我在那里添加了一个控制器和动作相等的检查,因为IsCurrentNode似乎比较节点拥有的键,不幸的是这些键是不同的。

我知道这乍一看像是一个模糊的问题,但我不想在这里开始讨论,我想知道这是否是一种可以做到这一点的好方法(或者什么是更好/更容易阅读的方法),是否有人可以解释我那些菜单调用,以及为什么我必须把可见性设置的方式我做了这个工作。

如果你想摆弄一下这个,你可以在这里下载这个"完整的"示例项目(Visual Studio 2012)。

这是一个很好的方法来设置一个2级导航(两个菜单,每个级别一个)与突出显示包括面包屑使用MvcSiteMapProvide

这个问题已经有一段时间没有答案了。

用上面描述的菜单结构建立了一个网站,并运行了一段时间,我想说YES,以解决最初的问题,这是否是一个有效的方式来建立两级网站导航。

然而,对于子问题,我还没有找到更令人满意的答案。(即确定当前节点与选定节点进行比较,并澄清@Html.MvcSiteMap.Menu呼叫。)
相关文章: