2012-02-15 3 views
14

Мне интересно, как можно добавить класс CSS на текущую страницу в вашей навигации при использовании ASP.NET MVC 3? Вот моя навигация в моем _Layout.cshtml файла:ASP.NET MVC - текущая страница подсветки в навигации

<p>@Html.ActionLink("Product Search", "Index", new { controller = "Home" }, new { @class = "current" }) 
       | @Html.ActionLink("Orders", "Index", new { controller = "Orders" }) 
       | @Html.ActionLink("My Account", "MyAccount", new { controller = "Account" }) 
       | @Html.ActionLink("Logout", "LogOff", new { controller = "Account" })</p> 

Как вы можете видеть, у меня есть 4 ссылки в моей навигации с первым, имеющим класс CSS «текущий» применяется к этому, я хотел бы быть возможность добавления/удаления этого класса в разные ссылки в моей навигации в зависимости от того, на какой странице находится пользователь. Это возможно?

Приветствия

ответ

12

Я бы рекомендовал использовать метод расширения для этого. Что-то вроде:

public static HtmlString NavigationLink(
    this HtmlHelper html, 
    string linkText, 
    string actionName, 
    string controllerName) 
{ 
    string contextAction = (string)html.ViewContext.RouteData.Values["action"]; 
    string contextController = (string)html.ViewContext.RouteData.Values["controller"]; 

    bool isCurrent = 
     string.Equals(contextAction, actionName, StringComparison.CurrentCultureIgnoreCase) && 
     string.Equals(contextController, controllerName, StringComparison.CurrentCultureIgnoreCase); 

    return html.ActionLink(
     linkText, 
     actionName, 
     controllerName, 
     routeValues: null, 
     htmlAttributes: isCurrent ? new { @class = "current" } : null); 
} 

Затем вы можете использовать его в View, включив в пространство имен вашего расширения и просто вызова метода:

@using MyExtensionNamespace; 

... 

    @Html.NavigationLink("Product Search", "Index", "Home") 
| @Html.NavigationLink("Orders", "Index", "Orders") 
| @Html.NavigationLink("My Account", "MyAccount", "Account") 
| @Html.NavigationLink("Logout", "LogOff", "Account") 

Это имеет преимущество держать бритву немного чище и легко можно повторно использовать в других представлениях.

+0

Спасибо, отмечен как ответ, поскольку я считаю, что это лучший способ сделать это, более чистые виды бритвы и повторное использование кода – CallumVass

+0

Для расширения 'HtmlHelper.ActionLink()' добавьте пространство имен для [LinkExtensions] (https://msdn.microsoft.com/en-us/library/system.web.mvc.html.linkextensions.aspx) следующим образом: 'using System.Web.Mvc.Html;' – Mike

24

Вы можете сделать это

@{ 
    var currentController = ViewContext.RouteData.Values["controller"] as string ?? "Home"; 
    var currentAction = ViewContext.RouteData.Values["action"] as string ?? "Index"; 
    var currentPage = (currentController + "-" + currentAction).ToLower(); 
} 

@Html.ActionLink("Product Search", "Index", "Home", null, 
       new { @class = currentPage == "home-index" ? "current" : "" }) 
@Html.ActionLink("MyAccount", "MyAccount", "Account", null, 
        new { @class = currentPage == "account-myaccount" ? "current" : "" }) 
+0

Спасибо! Это сработало – CallumVass

+0

Рад помочь! Хорошего дня! – dknaack

+0

@dknaack Вам не хватает a} до последнего)? –

8
@{ 
    var controller = ViewContext.RouteData.Values["controller"].ToString(); 
    var action = ViewContext.RouteData.Values["action"].ToString(); 
    var isActiveController = new Func<string, string, string, string, string>((ctrl, act, activeStyle, inactiveStyle) => controller == ctrl && action == act ? activeStyle : inactiveStyle); 
} 

Затем в атрибуте класса в вашем HTML вы можете сделать:

class="@isActiveController("controlername","action","activecssstyleclass","inactiveccsstyle")" 

просто другой способ @dknaack его ответ .. бит более общий и меньше функциональности, чтобы повторять в вашем коде.

2

Я использовал этот учебник, чтобы получить это сделать, это намного проще для понимания и занимает 2 минуты Hightlight Active menu item

+1

Недостатком этого подхода является то, что вы должны делать ViewBag.CurrentPage в каждом из действий вашего контроллера. – CallumVass

2

В моем случае предположим, что у меня есть домашняя страница и меню.

Добавить ViewBag.Active как заполнитель в домашней странице, как это:

@{ 
    ViewBag.Title = "Home"; 
    ViewBag.Active = "Home"; 
} 

Затем поместите его в li класс в качестве условия для активного или нет:

<li class="@(ViewBag.Active=="Home"? "active" : "")"> 
     <a href="@Url.Action("Index", "Home")"><span>@ViewBag.Title</span></a> 
</li> 
+0

Мне очень нравится этот ответ. Просто легко и очень практично. –

+0

Это очень хорошо работает с настройкой Navstart Bootstrap 4, где у li есть «активный» класс CSS, а также «nav-item», – JaneH

Смежные вопросы