2010-01-21 15 views
5

Estoy tratando de tener una buena idea sobre cómo modificar ciertas partes de la página en función de la página que estoy viendo. Puedo establecer ciertos elementos con el controlador de la página, pero estoy pensando más en los estados activos del menú de navegación global (que actualmente se representa con una RenderAction en la página maestra de la aplicación).Cómo puedo saber en qué página estoy en una aplicación MVC de ASP.NET

Al igual que si tengo algunos enlaces de navegación en la parte superior de la pantalla (utilizando SO es como un ejemplo)

Preguntas | Tags | Usuarios | ...

Si estoy en el área o en la página "Preguntas", quiero que el enlace Preguntas esté activo con un color diferente.

No quiero tener que administrar esto en cada página y además no quiero enviar valores a mi página maestra y luego enviarla a través de RenderAction porque creo que sería complicado. Lo que quiero es la acción para saber en qué área se encuentra la página representada y resaltar los elementos necesarios.

+0

No he llegado hoy ...con suerte mañana. – rball

Respuesta

6

La ViewMasterPage tiene una propiedad ViewContext. ViewContext contiene el RouteData. El RouteData debe tener una entrada para el nombre del controlador y la acción actual, si no son los predeterminados. Puede usarlos en su lógica en la página maestra para determinar qué elementos de navegación resaltar.

Del mismo modo, si utilizó una vista parcial para la navegación, tendría acceso a RouteData a través de la propiedad ViewContext en ViewUserControl.

EDIT: No creo que tenga que ser complicado.

<% 
    var current = this.ViewContext.RouteData.Values["controller"] as string ?? "home"; 
%> 

<ul> 
    <li><%= Html.ActionLink("Home", "index", "home", null, new { @class = current == "home" ? "highlight" : "" } %></li> 
    ... 
</ul> 

De hecho, hasta podría refactorizar a una extensión de HTML para que sea más fácil. Resulta que el asistente ya tiene una referencia al ViewContext por lo que ni siquiera necesita determinar el controlador actual en la vista. Tenga en cuenta que solo estoy mostrando una firma, puede agregar otras firmas para manejar datos de ruta adicionales y atributos html (estos deberían fusionarse) según sea necesario.

<ul> 
    <li><%= Html.NavLink("Home", "index", "home") %></li> 
    ... 
</ul> 

public static class HtmlHelperExtensions 
{ 
    public static string NavLink(this HtmlHelper helper, 
            string text, 
            string action, 
            string controller) 
    { 
      string current = helper.ViewContext.RouteData.Values["controller"] as string; 
      object attributes = null; 
      if (string.Equals(current, controller, StringComparison.OrdinalIgnoreCase)) 
      { 
       attributes = new { @class = "highlight" }; 
      } 

      return this.ActionLink(text, action, controller, null, attributes); 
    } 
} 
+0

Muy bien, no lo sabía. Déjame dar una oportunidad y ver si eso funcionará para mí. – rball

+0

eso es mucho más complicado de lo que debe ser. – Will

+0

Cambiar ViewContext.RouteData ["controller"] a ViewContext.RouteData.Values ​​["controller"] y funcionó para mí :) Gracias por la ayuda. – rball

0

Esto es algo que debe ser controlado desde el punto de vista propio. Si no desea modificar todas las vistas, puede crear un control de vista de usuario (archivos .ascx) y agregarlo a la página maestra.

+0

Ok, y luego en el control de vista del usuario, ¿cómo puedo decir en qué página estoy? Esa es mi pregunta. – rball

3

¡Buena pregunta!

En el pasado solía resolver esto comprobando los valores de RouteData del controlador y la acción. Pero ahora estoy usando MvcContrib MenuBuilder para hacer este tipo de trabajo. mira en su código de muestra para ver cómo trabajar con esto.

+0

Bien, buena sugerencia, voy a echar un vistazo. – rball

+0

¿Tienes un enlace a su código de muestra? Busqué en Google sin éxito – rball

+2

http://mvccontrib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37422, encontrará el ejemplo en el paquete del código fuente, solución MvcContrib.Samples.UI, en la carpeta Samples. –

1

Teniendo en cuenta lo siguiente en Page.Master:

<head runat="server"> 
    <link href="Standard.CSS" rel="stylesheet" type="text/css" /> 
    <asp:ContentPlaceHolder ID="header" runat="server" /> 
</head> 
<!-- and later on in the file --> 
<ul> 
    <li> 
    <a href="/questions" class="question">Questions</a> 
    </li> 
    <li> 
    <a href="/questions" class="user">Users</a> 
    </li> 
</ul> 

Dentro de la vista Users.aspx:

<asp:Content ID="header" ContentPlaceHolderID="header" runat="server"> 
    <title>User's Page</title> 
    <style type="text/css"> 
     .user 
     { 
      background-color:yellow; 
     } 
    </style> 
</asp:content> 

por lo que no tiene que hacer ningún tipo de análisis ruta raro o hurring este o durante eso. Simplemente agregue un ContentPlaceHolder en el encabezado de su página maestra, luego en cada vista proporcione alguna definición de CSS adicional dentro de este marcador de posición de contenido que hace que la página se vea como debería para esa vista en particular.

+2

Wow. Habla de quebradizo: tienes que hacer esto en cada página o está roto. Prefiero escribir un pequeño código que guardo con el sistema de navegación que tener todo este estilo incrustado diseminado a través de todas mis vistas. ¿Qué sucede si decides cambiar cómo se hace el resaltado? Entonces necesitas ir y cambiarlo a todas partes. Yuck. – tvanfosson

+1

Frágil? Lol. Al menos puedes cambiar tus vistas sin * tener que recompilar *. Además, esto permite que ** los diseñadores ** controlen cómo se ven sus vistas (que es su trabajo, por cierto) en lugar de los programadores. – Will

+0

Deje que el diseñador controle cómo se ve la página pidiéndole que diseñe las clases de CSS que aplique. Entonces aún puede cambiar el l & f sobre la marcha cambiando la hoja de estilo en lugar de visitar cada página de vista y cambiar el código. – tvanfosson

Cuestiones relacionadas