Как добавить" активный " класс в Html.Actionlink панели в ASP.NET в MVC
Я пытаюсь добавить "активный" класс в мой загрузочный navbar в MVC, но следующее не показывает активный класс, когда написано так:
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home", null, new {@class="active"})</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
это разрешает то, что выглядит как правильно отформатированный класс, но не работает:
<a class="active" href="/">Home</a>
в документации Bootstrap говорится, что теги " a " не должны использоваться в navbar, но выше я считаю, что это правильный способ добавления класса в Html.Actionlink панели. Есть ли другой (аккуратный) способ, которым я могу этого?
21 ответов
в Bootstrap active
класс должен быть применен к <li>
элемент, а не <a>
. См. первый пример здесь:http://getbootstrap.com/components/#navbar
способ обработки вашего стиля пользовательского интерфейса на основе того, что активно или нет, не имеет ничего общего с ASP.NET MVC ActionLink
помощником. Это правильное решение, чтобы следовать, как Bootstrap framework был построенный.
<ul class="nav navbar-nav">
<li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
Edit:
поскольку вы, скорее всего, будете повторно использовать меню на нескольких страницах, было бы разумно иметь способ применить этот выбранный класс автоматически на основе текущей страницы, а не копировать меню несколько раз и делать это вручную.
самый простой способ-просто использовать значения, содержащиеся в ViewContext.RouteData
, а именно Action
и Controller
значения. Мы могли бы построить на том, что у вас сейчас есть с что-то вроде этого:--15-->
<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
это не очень красиво в коде, но он выполнит работу и позволит вам извлечь меню в частичное представление, если хотите. Есть способы сделать это более чистым способом, но так как вы только начинаете, я оставлю это на этом. Удачи обучения ASP.NET MVC!
поздняя правка:
этот вопрос, похоже, получает немного трафика, поэтому я решил, что брошу более элегантное решение, используя Ан
Я manged, чтобы сделать это, добавив параметр view bag в asp.net mvc. Вот что я наделал!--3-->
добавил ViewBag.Current = "Scheduler";
параметр like на каждой странице
на странице макета
<ul class="nav navbar-nav">
<li class="@(ViewBag.Current == "Scheduler" ? "active" : "") "><a href="@Url.Action("Index","Scheduler")" target="_self">Scheduler</a></li>
</ul>
это решило мою проблему.
может быть немного поздно. Но надеюсь, это поможет.
public static class Utilities
{
public static string IsActive(this HtmlHelper html,
string control,
string action)
{
var routeData = html.ViewContext.RouteData;
var routeAction = (string)routeData.Values["action"];
var routeControl = (string)routeData.Values["controller"];
// both must match
var returnActive = control == routeControl &&
action == routeAction;
return returnActive ? "active" : "";
}
}
и использование как следовать:
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class='@Html.IsActive("Home", "Index")'>
@Html.ActionLink("Home", "Index", "Home")
</li>
<li class='@Html.IsActive("Home", "About")'>
@Html.ActionLink("About", "About", "Home")
</li>
<li class='@Html.IsActive("Home", "Contact")'>
@Html.ActionLink("Contact", "Contact", "Home")
</li>
</ul>
</div>
получил ссылку от http://www.codingeverything.com/2014/05/mvcbootstrapactivenavbar.html
Я знаю, что этот вопрос старый, но я просто хотел бы добавить свой голос здесь. Я считаю, что неплохо оставить знание о том, активна ли ссылка на контроллер представления.
Я бы просто установил уникальное значение для каждого представления в действии контроллера. Например, если бы я хотел сделать ссылку на домашнюю страницу активной, я бы сделал что-то вроде этого:
public ActionResult Index()
{
ViewBag.Title = "Home";
ViewBag.Home = "class = active";
return View();
}
тогда, на мой взгляд, я напишу что-то вроде этого:
<li @ViewBag.Home>@Html.ActionLink("Home", "Index", "Home", null, new { title = "Go home" })</li>
когда вы перейдите на другую страницу, скажем, программы, ViewBag.Home не существует (вместо ViewBag.Программы); поэтому ничего не отображается, даже class="". Я думаю, что это чище как для ремонтопригодности, так и для чистоты. Я всегда хочу оставить логику вне поля зрения, насколько это возможно.
вы можете попробовать это: В моем случае я загружаю меню из базы данных на основе доступа на основе ролей, напишите код на каждом представлении, которое вы хотите активировать на основе вашего представления.
<script type="text/javascript">
$(document).ready(function () {
$('li.active active-menu').removeClass('active active-menu');
$('a[href="/MgtCustomer/Index"]').closest('li').addClass('active active-menu');
});
</script>
Это решение просто для Asp.net MCV 5.
создать статический класс, например
Utilitarios.cs
.-
внутри класса создайте статический метод:
public static string IsLinkActive(this UrlHelper url, string action, string controller) { if (url.RequestContext.RouteData.Values["controller"].ToString() == controller && url.RequestContext.RouteData.Values["action"].ToString() == action) { return "active"; } return ""; }
-
вызов такой
<ul class="sidebar-menu" data-widget="tree"> <li class="header">HEADER</li> <li class="@Url.IsLinkActive("Index", "Home")"> <a href="@Url.Action("Index", "Home")"><i class="fa fa-link"></i> <span>Home</span></a> </li> <li class="@Url.IsLinkActive("About", "Home")"> <a href="@Url.Action("About", "Home")"><i class="fa fa-link"></i><span>About</span></a> </li> </ul>
добавить '.ToString ' для улучшения сравнения ASP.NET MVC
<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
--
возможно с лямбда-функцией
@{
string controllerAction = ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString();
Func<string, string> IsSelected= x => x==controllerAction ? "active" : "";
}
затем использования
@Html.ActionLink("Inicio", "Index", "Home", new { area = "" }, new { @class = IsSelected("HomeIndex")})
ответ @dombenoit работает. Хотя он вводит некоторый код для поддержания. Проверьте этот синтаксис:
using (var nav = Html.Bootstrap().Begin(new Nav().Style(NavType.NavBar).SetLinksActiveByControllerAndAction()))
{
@nav.ActionLink("Link 1", "action1")
@nav.ActionLink("Link 2", "action2")
@nav.Link("External Link", "#")
}
обратите внимание на использование .SetLinksActiveByControllerAndAction()
метод.
Если вам интересно, что делает этот синтаксис можно проверить TwitterBootstrapMVC
Я изменил дома "не очень" ответ и сделал дело. Иногда два контроллера имеют конфликтующие имена действий (т. е. индекс), поэтому я делаю это:
<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "HomeIndex" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "AboutIndex" ? "active" : "")">@Html.ActionLink("About", "Index", "About")</li>
<li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "ContactHome" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
Я понял, что эта проблема была общей проблемой для некоторых из нас, поэтому я опубликовал свое собственное решение с помощью пакета nuget. Ниже вы можете увидеть, как это работает. Надеюсь, это будет полезно.
Примечание: этот пакет nuget-мой первый пакет. Так что если вы видите ошибку, пожалуйста, дайте обратную связь. Спасибо.
-
установите пакет или загрузите исходный код и добавьте свой проект
-Install-Package Betalgo.MvcMenuNavigator
-
добавьте свои страницы в перечислимые
public enum HeaderTop { Dashboard, Product } public enum HeaderSub { Index }
-
поместите фильтр в верхней части вашего Controllor или Action
[MenuNavigator(HeaderTop.Product, HeaderSub.Index)] public class ProductsController : Controller { public async Task<ActionResult> Index() { return View(); } [MenuNavigator(HeaderTop.Dashboard, HeaderSub.Index)] public async Task<ActionResult> Dashboard() { return View(); } }
-
и использовать его в макете заголовка, как это
@{ var headerTop = (HeaderTop?)MenuNavigatorPageDataNavigatorPageData.HeaderTop; var headerSub = (HeaderSub?)MenuNavigatorPageDataNavigatorPageData.HeaderSub; } <div class="nav-collapse collapse navbar-collapse navbar-responsive-collapse"> <ul class="nav navbar-nav"> <li class="@(headerTop==HeaderTop.Dashboard?"active selected open":"")"> <a href="@Url.Action("Index","Home")">Dashboard</a> </li> <li class="@(headerTop==HeaderTop.Product?"active selected open":"")"> <a href="@Url.Action("Index", "Products")">Products</a> </li> </ul>
Подробнее: https://github.com/betalgo/MvcMenuNavigator
если это не отображается вообще, причина в том, что вам нужно два @ sign:
@@class
но я считаю, что вам может понадобиться активный класс на теге "li", а не на теге "a". согласно слишком bootstrap docs (http://getbootstrap.com/components/#navbar-default):
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Messages</a></li>
</ul>
поэтому ваш код будет:
<ul class="nav navbar-nav">
<li class="active">@Html.ActionLink("Home", "Index", "Home", null)</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
мы также можем создать UrlHelper
из RequestContext, который мы можем получить от самого MvcHandler. Поэтому я верю для тех, кто хочет сохранить эту логику в шаблонах бритвы следующим образом, было бы полезно:
- в корне проекта создайте папку с именем
AppCode
. - создайте там файл с именем
HtmlHelpers.cshtml
-
создайте там помощника:
@helper MenuItem(string action, string controller) { var mvcHandler = Context.CurrentHandler as MvcHandler; if (mvcHandler != null) { var url = new UrlHelper(mvcHandler.RequestContext); var routeData = mvcHandler.RequestContext.RouteData; var currentAction = routeData.Values["action"].ToString(); var currentController = routeData.Values["controller"].ToString(); var isCurrent = string.Equals(currentAction, action, StringComparison.InvariantCultureIgnoreCase) && string.Equals(currentController, controller, StringComparison.InvariantCultureIgnoreCase); <div class="@(isCurrent ? "active" : "")"> <div>@url.Action(action, controller)</div> </div> } }
-
тогда мы можем использовать наши взгляды, как это:
@HtmlHelpers.MenuItem("Default", "Home")
надеюсь, что это поможет кому-то.
Я также искал решение, и jQuery очень помог. Во-первых, вам нужно дать ' id ' для вашего <li>
элементы.
<li id="listguides"><a href='/Guides/List'>List Guides</a></li>
после этого на странице макета вы можете сказать jQuery, который <li>
элемент должен быть выделен, на ваш взгляд.
@section Scripts{
<script type="text/javascript">
$('#listguides').addClass('selected');
</script>
}
Примечание: Вы должны иметь @RenderSection("scripts", required: false)
в макет страницы, перед </body>
тег, чтобы добавить этот раздел.
надеюсь, это поможет, ниже, как ваше меню может быть:
<ul class="nav navbar-nav">
<li><a href="@Url.Action("Index", "Home")" class="@IsMenuSelected("Index","Home", "active")">Home</a></li>
<li><a href="@Url.Action("About", "Home")" class="@IsMenuSelected("About", "Home", "active")">About</a></li>
<li><a href="@Url.Action("Contact", "Home")" class="@IsMenuSelected("Contact", "Home", "active")">Contact</a></li>
</ul>
и добавьте ниже вспомогательную функцию MVC под тегом html.
@helper IsMenuSelected(string actionName, string controllerName, string className)
{
var conname = ViewContext.RouteData.Values["controller"].ToString().ToLower();
var actname = ViewContext.RouteData.Values["action"].ToString().ToLower();
if (conname == controllerName.ToLower() && actname == actionName.ToLower())
{
@className;
}
}
Я сослался на ответ от http://questionbox.in/add-active-class-menu-link-html-actionlink-asp-net-mvc/
Я хотел бы предложить это решение, которое основано на первой части ответа Dom.
сначала мы определяем две переменные: "действие" и "контроллер" и используем их для определения активной ссылки:
{ string controller = ViewContext.RouteData.Values["Controller"].ToString();
string action = ViewContext.RouteData.Values["Action"].ToString();}
и затем:
<ul class="nav navbar-nav">
<li class="@((controller == "Home" && action == "Index") ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@((controller == "Home" && action == "About") ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@((controller == "Home" && action == "Contact") ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
теперь он выглядит лучше и не нуждается в более сложных решениях.
Я сделал комбинацию ответов выше и сделал свое решение.
Так..
сначала в блоке razor создайте одну строковую переменную, которая будет содержать значение имени контроллера и действие, вызываемое пользователем.
@{
string controllerAction = ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString();
}
затем используйте комбинацию кода HTML и Razor:
<ul class="nav navbar-nav">
<li class="@(controllerAction == "HomeIndex" ? "active" : "" )">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(controllerAction == "AboutIndex" ? "active" : "" )">@Html.ActionLink("About", "Index", "About")</li>
<li class="@(controllerAction == "HomeContact" ? "active" : "" )">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
Я думаю, что это хорошо, потому что вам не нужно обращаться к "ViewContext.RouteData.Значения" каждый раз, чтобы получить имя контроллера и имя действия.
мое решение этой проблемы составляет
<li class="@(Context.Request.Path.Value.ToLower().Contains("about") ? "active " : "" ) nav-item">
<a class="nav-link" asp-area="" asp-controller="Home" asp-action="About">About</a>
</li>
лучшим способом может быть добавление метода расширения Html для возврата текущего пути для сравнения с link
учитывая то, что опубликовал Дамит, мне нравится думать, что вы можете просто квалифицировать активный Viewbag.Название (рекомендуется для заполнения на страницах контента, позволяя _Layout.cshtml
страница для удержания ваших ссылок). Также обратите внимание, что если вы используете вложенные пункты меню Он также отлично работает:
<li class="has-sub @(ViewBag.Title == "Dashboard 1" || ViewBag.Title == "Dashboard 2" ? "active" : "" )">
<a href="javascript:;">
<b class="caret"></b>
<i class="fa fa-th-large"></i>
<span>Dashboard</span>
</a>
<ul class="sub-menu">
<li class="@(ViewBag.Title == "Dashboard 1" ? "active" : "")"><a href="index.html">Dashboard v1</a></li>
<li class="@(ViewBag.Title == "Dashboard 2" ? "active" : "")"><a href="index_v2.html">Dashboard v2</a></li>
</ul>
</li>
Я считаю, что вот более чистый и более мелкий код, чтобы сделать выбранное меню "активным":
<ul class="navbar-nav mr-auto">
<li class="nav-item @Html.IfSelected("Index")">
<a class="nav-link" href="@Url.Action("Index", "Home")">Home</a>
</li>
<li class="nav-item @Html.IfSelected("Controls")">
<a class="nav-link" href="@Url.Action("Controls", "Home")">MVC Controls</a>
</li>
<li class="nav-item @Html.IfSelected("About")">
<a class="nav-link" href="@Url.Action("About", "Home")">About</a>
</li>
</ul>
public static string IfSelected(this HtmlHelper html, string action)
{
return html
.ViewContext
.RouteData
.Values["action"]
.ToString() == action
? " active"
: "";
}