2008-11-13 4 views
13

¿Cómo creo una navegación con pestañas con la pestaña "Actual" resaltada en la IU?¿Una forma fácil de configurar la pestaña activa usando controladores y un control de usuario en ASP.NET MVC?

+0

Por favor, frasee estos en forma de pregunta primero, y luego proporcione la respuesta como una publicación separada. Eliminaré mi voto negativo cuando vea que lo has arreglado. De lo contrario, tendré que cerrarlo como 'no es una pregunta real'. –

+1

Se lo arregló para él. – FlySwat

+0

La pregunta era tan grande y ahora tan pequeña: P haha ​​ –

Respuesta

10

Antes de MVC Miré la ruta del archivo y descubrí qué pestaña era actual. Ahora es mucho más fácil, puede asignar la pestaña actual basada en el controlador actual.

Compruébelo usted mismo ...

mayor parte del trabajo sucede en el control de usuario.

public partial class AdminNavigation : ViewUserControl 
{ 
    /// <summary> 
    /// This hold a collection of controllers and their respective "tabs." Each Tab should have at least one controller in the collection. 
    /// </summary> 
    private readonly IDictionary<Type, string> dict = new Dictionary<Type, string>(); 

    public AdminNavigation() 
    { 
     dict.Add(typeof(BrandController), "catalog"); 
     dict.Add(typeof(CatalogController), "catalog"); 
     dict.Add(typeof(GroupController), "catalog"); 
     dict.Add(typeof(ItemController), "catalog"); 
     dict.Add(typeof(ConfigurationController), "configuration"); 
     dict.Add(typeof(CustomerController), "customer"); 
     dict.Add(typeof(DashboardController), "dashboard"); 
     dict.Add(typeof(OrderController), "order"); 
     dict.Add(typeof(WebsiteController), "website"); 
    } 

    protected string SetClass(string linkToCheck) 
    { 
     Type controller = ViewContext.Controller.GetType(); 
     // We need to determine if the linkToCheck is equal to the current controller using dict as a Map 
     string dictValue; 
     dict.TryGetValue(controller, out dictValue); 

     if (dictValue == linkToCheck) 
     { 
      return "current"; 
     } 
     return ""; 
    } 
} 

Luego, en su parte Ascx de la llamada usercontol en el método setClass para comprobar el enlace en contra de la dict. De la misma manera:

<li class="<%= SetClass("customer") %>"><%= Html.ActionLink<CustomerController>(c=>c.Index(),"Customers",new{@class="nav_customers"}) %></li> 

Todo lo que necesita ahora es el CSS para resaltar su pestaña actual. Hay un montón de diferentes maneras de hacer esto, pero se puede empezar con algunas ideas aquí: http://webdeveloper.econsultant.com/css-menus-navigation-tabs/ Ah, y no se olvide de poner el control de usuario en su página (o MasterPage) ...

<% Html.RenderPartial("AdminNavigation"); %> 
+0

¿Funciona IDictionary? Parece que debería ser Dictionary en su lugar. –

+0

¿Qué sucede cuando un controlador tiene dos acciones? –

+1

@Anthony: este código funciona, está en producción ahora. @ Anthony2: ¿quiere decir que quiere una pestaña diferente resaltada por acción del controlador? Esto no ayudará eso. Sugeriría poner su navegador específico de controlador en un control de usuario y declarar qué pestaña activar cuando incruste el UC en la página. –

3

Un método que estoy usando en un proyecto actual: esto también ayuda a otras necesidades de CSS específicas de la página.

primer lugar, un asistente de HTML que devuelve una cadena que representa el controlador de corriente y la acción:

public static string BodyClass(RouteData data) { 
    return string.Format("{0}-{1}", data.Values["Controller"], data.Values["Action"]).ToLower(); 
} 

A continuación, agregue una llamada a este helper en su página maestra:

<body class="<%=AppHelper.BodyClass(ViewContext.RouteData) %>"> 
... 
</body> 

Ahora, puede orientar páginas específicas con su CSS. Para responder a su pregunta exacta sobre la navegación:

#primaryNavigation a { ... } 
.home-index #primaryNavigation a#home { ... } 
.home-about #primaryNavigation a#about { ... } 
.home-contact #primaryNavigation a#contact { ... } 
/* etc. */ 
10

Escribí algunas clases simples de ayuda para resolver este problema. La solución se ve tanto en el controlador que se usa como en la acción del controlador.

public static string ActiveTab(this HtmlHelper helper, string activeController, string[] activeActions, string cssClass) 
{ 
    string currentAction = helper.ViewContext.Controller. 
    ValueProvider.GetValue("action").RawValue.ToString(); 
    string currentController = helper.ViewContext.Controller. 
    ValueProvider.GetValue("controller").RawValue.ToString(); 
    string cssClassToUse = currentController == activeController && 
          activeActions.Contains(currentAction) 
          ? cssClass 
          : string.Empty; 
    return cssClassToUse; 
} 

Puede la llamada de este método de extensión con:

Html.ActiveTab("Home", new string[] {"Index", "Home"}, "active") 

Esto devolverá "activo" si estamos en el HomeController ya sea en el "Índice" o la acción "Inicio". También agregué algunas sobrecargas adicionales a ActiveTab para que sea más fácil de usar, puedes leer la publicación completa del blog en: http://www.tomasjansson.com/blog/2010/05/asp-net-mvc-helper-for-active-tab-in-tab-menu/

Espero que esto ayude a alguien.

Saludos, --Tomas

+0

funciona como un encanto, gracias. – Sotelo

+0

@ tomas-jansson Parece que la URL ya no se resuelve ... ¿es ahora http://blog.2mas.xyz/asp-net-mvc-helper-for-active-tab-in-tab-menu/ (?) – iokevins

+0

@iokevins Eso es correcto –

0

de MVC defecto Site.css viene con una clase llamada 'selectedLink' que se debe utilizar para esto.

Añadir lo siguiente a su lista de ul en _Layout.cshtml:

@{ 
    var controller = @HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString(); 
} 
<ul id="menu">     
    <li>@Html.ActionLink("Home", "Index", "Home", null, new { @class = controller == "Home" ? "selectedLink" : "" })</li> 
    ... 
</ul> 

Sé que esto no es limpio. Pero solo una forma rápida y sucia de hacer que las cosas funcionen sin interferir con vistas parciales o algo por el estilo.

Cuestiones relacionadas