问题描述
|
当我希望特定菜单链接在给定页面上处于活动状态时,我在Razor中使用以下方法:
在主版式上,我有以下检查:
var active = ViewBag.Active;
const string ACTIVE_CLASS = \"current\";
if (active == \"home\")
{
ViewBag.ActiveHome = ACTIVE_CLASS;
}
if (active == \"products\")
{
ViewBag.ActiveProducts = ACTIVE_CLASS;
}
等等
主版式上的html菜单:
<ul>
<li class=\"@ViewBag.ActiveHome\"><a href=\"/\">Home</a></li>
<li class=\"@ViewBag.ActiveProducts\"><a href=\"@Url.Action(\"index\",\"products\")\">Products</a></li>
</ul>
指定在其他视图上使用哪个布局页面时:
@{
ViewBag.Active = \"home\";
Layout = \"~/Views/Shared/_Layout.cshtml\";
}
与我当前使用的链接相比,有没有一种更好的方法来分隔活动链接?
解决方法
更好的方法是使用HTML帮助器:
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class MenuExtensions
{
public static MvcHtmlString MenuItem(
this HtmlHelper htmlHelper,string text,string action,string controller
)
{
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\");
}
li.InnerHtml = htmlHelper.ActionLink(text,controller).ToHtmlString();
return MvcHtmlString.Create(li.ToString());
}
}
接着:
<ul>
@Html.MenuItem(\"Home\",\"Home\",\"Home\")
@Html.MenuItem(\"Products\",\"Index\",\"Products\")
</ul>
要完成上述工作,您需要您的视图才能识别您的扩展名:在Webs.config的“视图”文件夹中,在名称空间标记内添加“ 5”。然后构建您的项目并关闭并重新打开要添加该视图的视图。
然后根据当前动作和控制器,辅助对象在生成锚点时将添加或不添加“ 6”类。
, 在Darin的示例上进行扩展,这里是完整类,该类在辅助程序上为RouteValues和HtmlAttributes添加了其他可选参数。实际上,它的行为就像基本的ActionLink。
using System;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace MYNAMESPACE.Helpers {
public static class MenuExtensions {
public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper,string controller,object routeValues = null,object htmlAttributes = null) {
var li = new TagBuilder(\"li\");
var routeData = htmlHelper.ViewContext.RouteData;
var currentAction = routeData.GetRequiredString(\"action\");
var currentController = routeData.GetRequiredString(\"controller\");
if (string.Equals(currentAction,StringComparison.OrdinalIgnoreCase) &&
string.Equals(currentController,StringComparison.OrdinalIgnoreCase)) {
li.AddCssClass(\"active\");
}
if (routeValues != null) {
li.InnerHtml = (htmlAttributes != null)
? htmlHelper.ActionLink(text,routeValues,htmlAttributes).ToHtmlString()
: htmlHelper.ActionLink(text,routeValues).ToHtmlString();
}
else {
li.InnerHtml = htmlHelper.ActionLink(text,controller).ToHtmlString();
}
return MvcHtmlString.Create(li.ToString());
}
}
}
并在View文件夹的web.config中:
<system.web.webPages.razor>
<host ... />
<pages ... >
<namespaces>
...
...
<add namespace=\"MYNAMESPACE.Helpers\" />
</namespaces>
</pages>
</system.web.webPages.razor>
, 如果您想在文本中包含HTML格式,请使用此InnerHtml;
li.InnerHtml = \"<a href=\\\"\" + new UrlHelper(htmlHelper.ViewContext.RequestContext).Action(action,controller).ToString() + \"\\\">\" + text + \"</a>\";
文字可能是\“ 粗体 b>普通\”;
, 已为RC2更新-对于那些想知道如何在MVC6 / Asp.Net 5中执行此操作的用户-相似但略有不同。现在没有MvcHtmlString
,而RouteData
的工作方式则完全不同。而且,上下文对象现在应该是IHtmlContent
而不是HtmlHelper
。
using System;
using Microsoft.AspNet.Mvc.Rendering;
public static class MenuExtensions
{
public static IHtmlContent MenuItem(
this IHtmlHelper htmlHelper,string controller
)
{
var li = new TagBuilder(\"li\") { TagRenderMode = TagRenderMode.Normal };
var routeData = htmlHelper.ViewContext.RouteData;
var currentAction = routeData.Values[\"action\"].ToString();
var currentController = routeData.Values[\"controller\"].ToString();
if (string.Equals(currentAction,StringComparison.OrdinalIgnoreCase))
{
li.AddCssClass(\"active\");
}
li.InnerHtml.AppendHtml(htmlHelper.ActionLink(text,controller));
return li;
}
}
, 即使在新的Visual Studio 2013 MVC5 / Bootstrap项目上,此代码也对我非常有用。还要注意,您可以更改li.AddCssClass(\“ active \”);如果要单独保留Bootstrap \“ active \\”类,则该行指向一个自定义类。我在项目的Site.css文件中添加了一个名为“ activemenu”的文件,并在此进行了任何想要的特定导航栏样式更改。
上面代码中的行仅更改为此代码,以使其全部正常工作:
li.AddCssClass(\"activemenu\");
在Site.css中,出于我的目的添加了一个简单的类:
.activemenu {
text-decoration: underline;
}
或者,您可以更改背景颜色和/或边框等。
, 这是达林类的扩展,可以在链接文本中插入html而不是简单的文本
using System;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace YourNameSpaceHere
{
public static class MenuExtensions
{
public static MvcHtmlString MenuItem(
this HtmlHelper htmlHelper,string html,string controller
)
{
var li = new TagBuilder(\"li\");
var routeData = htmlHelper.ViewContext.RouteData;
var currentAction = routeData.GetRequiredString(\"action\");
var currentController = routeData.GetRequiredString(\"controller\");
if (string.Equals(currentAction,StringComparison.OrdinalIgnoreCase))
{
li.AddCssClass(\"active\");
}
//generate a unique id for the holder and convert it to string
string holder = Guid.NewGuid().ToString();
string anchor = htmlHelper.ActionLink(holder,controller).ToHtmlString();
//replace the holder string with the html
li.InnerHtml = anchor.Replace(holder,html);
return MvcHtmlString.Create(li.ToString());
}
}
}
并像这样使用它:
<ul>
@Html.MenuItem(\"<span class\'ClassName\'>Home</span>\",\"Home\")
</ul>