2012-02-15 22 views
14

Me pregunto cómo es posible agregar una clase de CSS a la página actual en su navegación cuando se utiliza ASP.NET MVC 3? Aquí está mi navegación en mi archivo _Layout.cshtml:ASP.NET MVC - Destacando la página actual en la navegación

<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> 

Como se puede ver que tengo 4 enlaces en mi navegación con el primero que tiene la clase CSS "actual" que se le aplica, me gustaría estar capaz de agregar/eliminar esta clase a los diferentes enlaces en mi navegación, dependiendo de en qué página esté el usuario. es posible?

Saludos

Respuesta

12

yo recomendaría usar un método de extensión para esto. Algo así como:

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); 
} 

A continuación, puede usarlo en su opinión, incluyendo el espacio de nombres de su extensión y simplemente llamando a su método:

@using MyExtensionNamespace; 

... 

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

Esto tiene la ventaja de mantener su maquinilla de afeitar un poco más limpio y es fácilmente reutilizable en otras vistas.

+0

Gracias, marcada como respuesta, ya que creo que esta es la mejor manera de hacerlo, vistas más limpias de la máquina de afeitar y reutilización del código – CallumVass

+0

Para la extensión 'HtmlHelper.ActionLink()', agregue el espacio de nombres para [LinkExtensions] (https://msdn.microsoft.com/en-us/library/system.web.mvc.html.linkextensions.aspx) de esta manera: 'using System.Web.Mvc.Html;' – Mike

24

Usted puede hacer esto

@{ 
    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

Gracias! Esto funcionó – CallumVass

+0

¡Me alegra ayudar! ¡Que tengas un buen día! – dknaack

+0

@dknaack ¿No te falta un} antes del último? –

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); 
} 

Luego, en su atributo de clase en el código HTML que puede hacer:

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

Sólo una otra forma de @dknaack su respuesta ... un poco más genérico y menos funcionalidad para repetir en tu código.

2

He utilizado este tutorial para obtener este hecho, es mucho más fácil de entender y se tarda 2 minutos Hightlight Active menu item

+1

la desventaja de este enfoque es que tiene que hacer ViewBag.CurrentPage en cada una de las acciones de su controlador. – CallumVass

2

En mi caso, supongo que tengo una página de inicio y un menú.

Añadir un ViewBag.Active como un marcador de posición en la página de inicio de esta manera:

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

luego se coloca a su clase li como condición para activarlo o no:

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

Me gusta mucho esta respuesta. Simplemente fácil y muy práctico. –

+0

Esto funciona muy bien con la configuración de navegación de Bootstrap 4, donde el li tiene una clase CSS "activa" así como también "nav-item" – JaneH

Cuestiones relacionadas