ASP.NET MVC Menú Elemento Seleccionado

ACEPTAR de nuevo a MVC. Yo le había pedido este pregunta anterior y recibió una respuesta, pero me pregunto si hay una solución más sencilla.

Decir que tengo una página principal con un menú establecido como una lista desordenada. Cómo se podría ir sobre la configuración de una clase css en el elemento de menú actualmente seleccionado?

EDICIÓN:

Estoy usando el menú como se trata de la instalación de la caja cuando se inicia una nueva aplicación mvc

<ul id="menu">              
   <li><%: Html.ActionLink("Home", "Index", "Home")%></li>
   <li><%: Html.ActionLink("About", "About", "Home")%></li>
</ul>
  • ¿Cómo estás generando el menú?
  • Confundido por la downvote…es una cuestión básica del curso, por auto proclamado MVC principiante. Buscando un poco de orientación sobre el tema.
  • Usted puede haber recibido un downvote porque no proporcionar el código inicialmente. Yo no me preocuparía por eso.
  • no estoy realmente preocupado. Me gusta mi reputación para aumentar lol
InformationsquelleAutor stephen776 | 2011-01-11

7 Kommentare

  1. 27

    La respuesta de Jakub Konecki me llevó en la dirección correcta… aquí está el controlador de acción que terminó con:

        [ChildActionOnly]
        public ActionResult MainMenu()
        {
            var items = new List<MenuItem>
            {
                new MenuItem{ Text = "Home", Action = "Index", Controller = "Home", Selected=false },
                new MenuItem{ Text = "My Profile", Action = "Index", Controller = "Profile", Selected = false},
                new MenuItem{ Text = "About", Action = "About", Controller = "Home", Selected = false }
            };
    
            string action = ControllerContext.ParentActionViewContext.RouteData.Values["action"].ToString();
            string controller = ControllerContext.ParentActionViewContext.RouteData.Values["controller"].ToString();
    
            foreach (var item in items)
            {
                if (item.Controller == controller && item.Action == action)
                {
                    item.Selected = true;
                }
            }
    
            return PartialView(items);
        }

    Espero que esto ayude a alguien.

    • +1 – gracias esteban. estaba mirando a mí mismo ayer, y esto era muy útil. por cierto, ¿usas html.renderpartial o renderaction para esto?? también, se que el emplazamiento de la partialview en su masterpage??
    • No en frente de mi equipo ahora mismo, pero estoy bastante seguro de que me fui con renderaction en la masterpage
  2. 18

    Debe pasar toda la información relevante en el Modelo. Lo ideal sería que el menú se muestra como una Vista Parcial por un método de controlador. Tengo un controlador de Navegación con acciones como el MainMenu, FooterMenu, pan rallado, etc que hacen que las partes individuales.

    Su modelo será una colección de elementos de menú como:

        public class MenuItemModel
        {
            public MenuItemModel()
            {
                SubMenu = new List<MenuItemModel>();
            }
    
            public string Text { get; set; }
            public string Controller { get; set; }            
            public string Action { get; set; }
            public bool Selected { get; set; }
    
            public List<MenuItemModel> SubMenu { get; private set; }
        }

    El Controlador va a crear una colección de elementos de menú y pasar a la vista con el correspondiente elemento seleccionado. A continuación, la vista puede ser tan simple como:

    <ul id="menu">     
        <% foreach(var menuItem in Model.MenuItems) { %> 
            <li><%: Html.ActionLink(menuItem.Text, menuItem.Action, menuItem.Controller, null, new { @class = menuItem.Selected ? "selected" : "" })%></li>
        <% } %>
    </ul>
    • Pero, ¿cómo puedo agregar la ‘selección’ de la clase a en el enlace que hace referencia a la página actual…parece como si la solución sería aplicar siempre la clase a el primer elemento de la lista…
    • Tengo esta trabajando en su mayor parte. Me preguntaba si a usted le sucede que tiene un ejemplo de controlador para este. Mi menú está trabajando simplemente no estoy claro sobre cómo ajustar el elemento seleccionado en el controlador de…
    • Excelente respuesta. Una de las mejoras para el ActionLink htmlAttributes parámetro: menuItem.Selected ? new { @class = "selected" } : null
    • En el _Layout.cshtml usted necesita usar algo como @Html.La Acción(«MainMenu», «Navegación»)
  3. 4

    stephen,

    aquí está mi contribución a la fiesta. un recursiva de función en línea para rellenar el <ul><li> como muchas profundidades, como es requerido (aquí todo el archivo ascx):

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<GBC_Art.Controllers.MenuItemModel>>" %>
    <%@ Import Namespace="GBC_Art.Controllers" %>
    <%
        Action<List<MenuItemModel>, int> printNodesRecursively = null;
        printNodesRecursively = (List<MenuItemModel> nodeList, int depth) =>
        {
            if (nodeList == null || nodeList.Count == 0) return;
    %>
        <ul<%= depth == 0 ? " id='menu'" : ""%>>  
    <%
        foreach (var menuItem in nodeList)
        {
        %>
        <li><%= Html.ActionLink(menuItem.Text, menuItem.Action, menuItem.Controller, null, new { @class = menuItem.Selected ? "selected" : "" })%>
            <%printNodesRecursively(menuItem.SubMenu, depth + 1);%>
        </li>
        <%
            }
    %>
        </ul>
    <%
        };
        List<MenuItemModel> nodes = Model; 
        printNodesRecursively(nodes, 0);
    %>

    de uso -> se llama como un partialview a través de la controladora como por su ejemplo de arriba.

    saludos

    • impresionante…este iba a ser el siguiente en mi lista. Gracias por el aporte
    • esto probablemente debería ser un wiki o algo ya que este va a ser un problema común para los nuevos en el MVC como yo
    • usted podría estar en lo correcto volver a la wiki de pensamiento. si no se mueven, que recuerda a la aceleración de la respuesta, ya que no cuentan en la wiki 🙂
  4. 4

    Aquí es otra posibilidad, más simple, en mi opinión, el uso de HTML Helper:

    Clase CSS

    ul#menu li.selected a {
      background-color: #034af3;
      color: #e8eef4;
    }

    HTML Helper

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.Mvc;
    
    namespace MyWebApp.WebUI.HtmlHelpers
    {
      public static class HtmlHelperExtensions
      {
        public static string ActivePage(this HtmlHelper helper, string controller, string action)
        {
          string classValue = "";
    
          string currentController = helper.ViewContext.Controller.ValueProvider.GetValue("controller").RawValue.ToString();
          string currentAction = helper.ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();
    
          if (currentController == controller && currentAction == action)
          {
            classValue = "selected";
          }
    
          return classValue;
        }
      }
    }

    Menú en el Diseño de :

    <nav>
      <ul id="menu">
        <li class="@Html.ActivePage("Home", "Index")">@Html.ActionLink("Home", "Index", "Home")</li>
        <li class="@Html.ActivePage("Home", "About")">@Html.ActionLink("About", "About", "Home")</li>
      </ul>
    </nav>

    Más información aquí : http://bubblogging.wordpress.com/2012/02/12/mvc-add-selected-class-to-menu/

  5. 2

    Sólo el aprendizaje de MVC ahora, pero me encontré con este problema y he descubierto un método más rápido para lograr esto. Se basa en direcciones Url de forma coherente, y no se ve afectado por las cadenas de consulta.

    <ul id="menu">              
      <li @(Request.Path.Equals("/") ? Html.Raw("class=\"selected\"") : Html.Raw(""))>
        @Html.ActionLink("Home", "Index", "Home")</li>
      <li @(Request.Path.Equals("/about") ? Html.Raw("class=\"selected\"") : Html.Raw(""))>
        @Html.ActionLink("About", "About", "Home")%></li>
    </ul>

    Por supuesto, usted puede manejar de varias direcciones Url que muestra el mismo elemento seleccionado a través de OR lógica o hacer una lista. Pero si usted está haciendo una lista, sería, por supuesto, quieres que en tu modelo. Usted podría tener una opción para resaltar un directorio entero por sólo la comprobación de que el inicio de la cadena de partidos.

    Como es, este sería el más adecuado para una más sitio web estático. Si se incluye esta en un LayoutPage, el mantenimiento es muy fácil, ya que no tienen clases extra o funciones para mantener. Obviamente esto no cortar si usted estaba trabajando en un CMS.

  6. 1

    Junto a todas las otras soluciones que usted puede utilizar este método para cargar los menús de forma dinámica a partir de la Base de datos y hacer el menú seleccionado activo y mantener el estado a través de la página web.

    en la página de Diseño:

    <body>
    <header>
       @{Html.RenderPartial("_MenuPartial"); }
    </header>
    @RenderBody()
    </body>

    Entonces su vista parcial contiene :

    <nav class="navMain">
    <ul>
       foreach (var menu in menuList)
       {
        <li id="@menu.Id"><a href="@menu.Url">@menu.Name</a></li>
       }
    </ul>
    </nav>

    Para activar el clic del menú, usted necesita una secuencia de comandos en la vista parcial. También ‘activo’ de la clase en nada, pero cambiando el color de fondo en el CSS.

    <script>
    var selector = '.navMain li';
    $(selector).on('click', function () {
        $(this).addClass('active').siblings().removeClass('active');
        var menuId = $(this).prop("id");
        localStorage.setItem('SelectedMenu', menuId);
    });

    Ya que establezca el atributo HREF para cada enlace del menú, vamos a perder la clase activa por posterior. Así que usted necesita para leer el menú seleccionado de localStorage y aplicarlo en el menú adecuado en vista parcial:

    <script>
    $(document).ready(function () {
        var activeMenuLocalStorage = localStorage.getItem('SelectedMenu');
        if (!isNaN(activeMenuLocalStorage)) {
        {
         $("#" + activeMenuLocalStorage).addClass('active');
        }
    });

  7. 0

    Más forma más sencilla cuando you don't want to change your code much .. Gracias @Hugo Hilario para el concepto

    using Microsoft.Web.Mvc;     
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    
    namespace Demo.Web.Mvc
    {
        public static class UIHelper
        {             
            public static MvcHtmlString ActivePage(this HtmlHelper helper, string linkText, string action, string controller)
            { 
                string currentController = helper.ViewContext.Controller.ValueProvider.GetValue("controller").RawValue.ToString();
                string currentAction = helper.ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();    
    
                var actionLink = helper.ActionLink(linkText, action,controller);
                var isCurrentRoute = currentController == controller;//&& currentAction == action; uncomment if you want to segregate by action also
    
                return MvcHtmlString.Create(string.Format("<li{0}>", isCurrentRoute ? " class=\"YourActiveCssClass\"" : string.Empty) + actionLink + "</li>");    
    
            }
        }
    }

    Página de diseño

    <div class="navbar-collapse collapse">
         <ul class="nav navbar-nav"> 
              @Html.ActivePage("User", "Index", "User") 
              @Html.ActivePage("State", "Index", "State") 
              @Html.ActivePage("City", "Index", "City") 
         </ul>                     
    </div>

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea