在默认的asp.net mvc项目中,在Site.Master文件中,有一个菜单导航列表:
- <%= Html.ActionLink("Home", "Index", "Home")%>
- <%= Html.ActionLink("About Us", "About", "Home")%>
这将在浏览器中呈现:
我希望能够根据被调用的视图动态设置活动列表项.也就是说,当用户查看主页时,我希望创建以下HTML:
我希望这样做的方式如下:
- class="active"<%}%>><%= Html.ActionLink("Home", "Index", "Home")%>
- class="active"<%}%>><%= Html.ActionLink("About Us", "About", "Home")%>
这里的关键位是<% if(actionName == "Index"){%> class="active"<%}%>
线.我不知道如何确定当前actionName是什么.
有关如何做到这一点的任何建议?或者,如果我完全走错了轨道,有没有更好的方法呢?
我自己做了一个帮助方法来处理这类事情.在我的母版页后面的代码中(可以推送到扩展方法......可能是更好的方法),我把下面的代码.
protected string ActiveActionLinkHelper(string linkText, string actionName, string controlName, string activeClassName) { if (ViewContext.RouteData.Values["action"].ToString() == actionName && ViewContext.RouteData.Values["controller"].ToString() == controlName) return Html.ActionLink(linkText, actionName, controlName, new { Class = activeClassName }); return Html.ActionLink(linkText, actionName, controlName); }
然后,我只是在我的页面中调用它:
<%= ActiveActionLinkHelper("Home", "Index", "Home", "selected")%>
在视图中,您可以使用以下命令获取当前操作名称:
ViewContext.RouteData.Values["action"].ToString()
您还可以尝试从其控制器名称和视图名称中检测当前所选选项卡,然后添加class属性.
public static string MenuActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName) { var htmlAttributes = new RouteValueDictionary(); if (helper.ViewContext.Controller.GetType().Name.Equals(controllerName + "Controller", StringComparison.OrdinalIgnoreCase)) { htmlAttributes.Add("class", "current"); } return helper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), htmlAttributes); }
在MVC 3 Razor View Engine中,您可以这样做:
@{string ctrName = ViewContext.RouteData.Values["controller"].ToString();}
- class="active"}>@ Html.ActionLink("Home", "Index", "Home")
- class="active"}>@ Html.ActionLink("About Us", "About", "Home")
当我有两个页面时我的样本工作:Home/About和它的控制器具有相同的名称索引,所以我得到控制器名称以区分操作.如果您想要采取行动,只需替换为以下内容:
@{string ctrName = ViewContext.RouteData.Values["action"].ToString();}
一个老问题,但希望有人可能会发现这非常有帮助.
在ViewBag中放置一些可用于识别页面的东西,我使用了ViewgBag.PageName
例如,在index.cshtml中,添加类似的内容
@{ ViewBag.PageName = "Index"; }
使用条件语句向每个链接项添加一个类,以便在访问的页面具有所需值时返回活动状态,否则返回空字符串.查看以下详细信息:
Home
About
Contact
为了贡献我自己的答案(在MVC4中测试),我采取了其他答案的几个最佳位,解决了一些问题,并添加了一个帮助程序来处理不一定通过Controller&Action解决的URL(例如,如果你有一个嵌入式CMS处理一些页面链接等)
该代码也可以在github上分叉:https://gist.github.com/2851684
/// /// adds the active class if the link's action & controller matches current request /// public static MvcHtmlString MenuActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues = null, object htmlAttributes = null, string activeClassName = "active") { IDictionary htmlAttributesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); if (((string)htmlHelper.ViewContext.RouteData.Values["controller"]) .Equals(controllerName, StringComparison.OrdinalIgnoreCase) && ((string)htmlHelper.ViewContext.RouteData.Values["action"]) .Equals(actionName, StringComparison.OrdinalIgnoreCase)) { // careful in case class already exists htmlAttributesDictionary["class"] += " " + activeClassName; } return htmlHelper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(routeValues), htmlAttributesDictionary); } /// /// adds the active class if the link's path matches current request /// public static MvcHtmlString MenuActionLink(this HtmlHelper htmlHelper, string linkText, string path, object htmlAttributes = null, string activeClassName = "active") { IDictionary htmlAttributesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); if (HttpContext.Current.Request.Path .Equals(path, StringComparison.OrdinalIgnoreCase)) { // careful in case class already exists htmlAttributesDictionary["class"] += " " + activeClassName; } var tagBuilder = new TagBuilder("a") { InnerHtml = !string.IsNullOrEmpty(linkText) ? HttpUtility.HtmlEncode(linkText) : string.Empty }; tagBuilder.MergeAttributes(htmlAttributesDictionary); tagBuilder.MergeAttribute("href", path); return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal)); }