MVC SiteMap提供程序,显示隐藏菜单项的父菜单

时间:2014-07-30 20:10:58

标签: asp.net-mvc-4 asp.net-mvc-5 mvcsitemapprovider

我使用MVC SiteMap Provider为我的网站创建菜单,并突出显示当前菜单项。

在我的控制器中,我有一个索引,详细信息,添加,编辑和删除方法。只有Index和Add方法可用作菜单项。

我还想在详细信息操作中突出显示当前主菜单项(即产品)。我该怎么做?

我试过了:

<mvcSiteMapNode title="Details" action="Details" visibility="IfSelected,!*" />

但是这并没有突出显示菜单,即使我不想要菜单,也会在菜单中显示详细信息。

然后我试了

<mvcSiteMapNode title="Details" action="Details" visibility="IfSelected,!*" preservedRouteParameters="id" />

其中突出显示了详细信息子菜单,但我宁愿在菜单中隐藏详细信息子菜单,只突出显示主菜单项(&#39;项目&#39;)。

1 个答案:

答案 0 :(得分:2)

你显然试图实现两件不同的事情,但你已将它们合并为一个问题。

首先,要进行CRUD操作,请查看文章How to Make MvcSiteMapProvder Remember a User's Position和随附的downloadable demos。具体来说,请查看标题为MvcSiteMapProvider-Forcing-A-Match的演示,因为它演示了如何嵌套节点,强制它们匹配当前请求,设置可见性,以及根据您选择的记录动态更改节点上的标题。 / p>

问题的第二部分实际上是关于更改输出HTML以突出显示菜单项,使用任何内置功能都无法做到这一点。为此,您需要直接编辑/Views/Shared/DisplayTemplates/SiteMapNodeModel.cshtml文件。这个文件由NuGet包添加到您的MVC项目中,您应该注意不要在升级时覆盖对它的更改。请注意,此文件由Menu,SiteMap和SiteMapPath HTML帮助程序共享,因此您应该make a copy for the menu或者注意始终对要编辑的特定HTML帮助程序使用分支逻辑。

要确定与当前页面最接近的匹配节点,您需要这一点剃刀代码。

@{var isClosestVisibleMenuItem = false;}
@if ((Model.IsCurrentNode || (Model.IsInCurrentPath && !Model.IsRootNode && !Model.Descendants.Any())) 
    && Model.SourceMetadata["HtmlHelper"].ToString() == "MvcSiteMapProvider.Web.Html.MenuHelper")
{
    isClosestVisibleMenuItem = true;
}

请注意,检查SourceMetadata值以确保我们引用Menu - 所有其他HTML帮助程序将始终将isClosestVisibleMenuItem变量设置为false。

然后,只需使用变量来告诉模板输出什么HTML。下面是一个示例,它将<b></b>放在菜单中最近的可见节点周围。在实际示例中,您可能希望将特定的CSS类添加到锚标记以突出显示它。

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

@{var isClosestVisibleMenuItem = false;}
@if ((Model.IsCurrentNode || (Model.IsInCurrentPath && !Model.IsRootNode && !Model.Descendants.Any())) && Model.SourceMetadata["HtmlHelper"].ToString() == "MvcSiteMapProvider.Web.Html.MenuHelper")
{
    isClosestVisibleMenuItem = true;
}

@if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper")  { 
    <text>@Model.Title</text>
} else if (Model.IsClickable) {

    if (isClosestVisibleMenuItem)
    {
        <b>
        @if (string.IsNullOrEmpty(Model.Description))
        {
            <a href="@Model.Url">@Model.Title</a>
        }
        else
        {
            <a href="@Model.Url" title="@Model.Description">@Model.Title</a>
        }
        </b>
    }
    else
    {
        if (string.IsNullOrEmpty(Model.Description))
        {
            <a href="@Model.Url">@Model.Title</a>
        }
        else
        {
            <a href="@Model.Url" title="@Model.Description">@Model.Title</a>
        }
    }
} else {
    if (isClosestVisibleMenuItem)
    {
        <b>@Model.Title</b>
    }
    else
    {
        <text>@Model.Title</text>   
    }
}

IfSelected用于特定用例,在这种情况下,您有一个深层次结构,并希望显示当前路径(无论多深),同时将菜单的其余部分保持在高水平。通常,这仅适用于菜单,不适用于其他HTML帮助程序。但是你的问题没有任何暗示,这就是你想要实现的目标。