Navigation menu with highlight in Asp.NET MVC?

后端 未结 7 906
广开言路
广开言路 2021-02-14 15:31

It\'s a simple question. How did stackoverflow do their menu in Asp.net MVC, with highlight on what page we are on.

相关标签:
7条回答
  • 2021-02-14 16:11

    The best way - create MVC helper (see previous answers) But if you don't want to do it and want to do quickly - remember about new feature in MVC 4.0 with set attributes of html tags (attribute will be avoid if it's set to null):

            @{
                string currentAction = ViewContext.RouteData.Values["action"].ToString().ToLower();
    
                string classUpcomingTime = null;
                string classArchive = null;
                string classReporting = null;
    
                switch (currentAction)
                {
                    case "upcomingtime":
                        classUpcomingTime = "active";
                        break;
                    case "archive":
                        classArchive = "active";
                        break;
                    case "reporting":
                        classReporting = "active";
                        break;
                }
    
                <ul class="nav navbar-nav">
                    <li class="@classUpcomingTime">
                        <a href="/Vacancy/UpcomingTime">Open Vacancies</a>
                    </li>
                    <li class="@classArchive">
                        <a href="/Vacancy/Archive">Archive</a>
    
                    <li class="@classReporting">
                        @*<a href="#">Reporting</a>*@
                        <a href="/Vacancy/Reporting">Reporting</a>
                    </li>
                </ul>
            }
    
    0 讨论(0)
  • 2021-02-14 16:14

    You could use a HTML Helper to create the menu. That way all the code is in one place.

    SiteMap HtmlHelper ASP.NET MVC has some information about a component that is available.

    0 讨论(0)
  • 2021-02-14 16:17

    For the purpose of this, i've writen some code down, there are some part that using my custom extension like Language, go ahead and use it, just ignore the minor part.

    This one i place on top of my Partial that contain the menu to get the action and controller, so that i can pass this to the extension.

    <%  string currentAction = ViewContext.RouteData.Values["action"].ToString();
        string currentController = ViewContext.RouteData.Values["controller"].ToString(); %>
    

    This is the sidebar Item, basically this will generate a "li" tag with a link and your custom class to indicate whether the link is currently used in the page / highlight.

    public static string SidebarItem(this System.Web.Mvc.HtmlHelper html, string currentAction, string currentController, string action, string controller, string languageKey, params object[] args)
    {
        TagBuilder tb = new TagBuilder("li");
        if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) && string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase))
        {
            tb.GenerateId("activemenu");
        }
        string text = html.Language(languageKey, args);
        string link = html.ActionLink(text, action, controller).ToHtmlString();
        tb.SetInnerText("{0}");
        return String.Format(tb.ToString(), "<span>"+link+"</span>");
    }
    

    and here is the actual usage of the code above

    <%= Html.SidebarItem(currentAction, currentController, "index", "home", "index") %>
    
    0 讨论(0)
  • 2021-02-14 16:19

    There is probably no MVC special magic that makes this happen.

    I'm sure:

    if( HttpContext.Current.Request.Path == "some some menu url" )
    

    or

    if( ViewContext_Or_ControllerContext.RouteData.Values["controller"] == "some value") 
    

    is used someplace.

    You could put this code in about three different locations ( View ( .aspx ), ViewModel, Custom HtmlHelper ) and they would all require that same bit of code.

    0 讨论(0)
  • 2021-02-14 16:25

    1.First create extention

    public class Extention
    {
        public static Dictionary<Menu, Menu> GetDictionary()
        {
            Dictionary<Menu, Menu> urls = new Dictionary<Menu, Menu>();
            urls.Add(new Menu { Controller = "AppHome", Action = "Index" }, new Menu { Controller = "AppHome", Action = "Index" });
            urls.Add(new Menu { Controller = "Home", Action = "Index" }, new Menu { Controller = "Home", Action = "Index" });
    
            return urls;
        }
    }
    public static class HtmlExtensions
    {
        public static MvcHtmlString ActionMenu(this HtmlHelper helper,String linkText,string actionName,String controllerName)
        {
            var tag= new TagBuilder("li");
            if(helper.ViewContext.RequestContext.IsCurrentRoute(null,controllerName,actionName)||
                helper.ViewContext.RequestContext.IsParentRoute(controllerName,actionName))
            {
                tag.AddCssClass("active");
            }
            else
            {
                tag.AddCssClass("inactive");
            }
            tag.InnerHtml = helper.ActionLink(linkText, actionName, controllerName).ToString();
            return MvcHtmlString.Create(tag.ToString());
        }
    }
    public static class RequestExtentions
    {
        public static bool IsCurrentRoute(this RequestContext context, String areaName)
        {
            return context.IsCurrentRoute(areaName, null, null);
        }
        public static bool IsCurrentRoute(this RequestContext context, String areaName, String controllerName)
        {
            return context.IsCurrentRoute(areaName, controllerName, null);
        }
        public static bool IsCurrentRoute(this RequestContext context, String areaName, String controllerName, params String[] actionNames)
        {
            var routeData = context.RouteData;
            var routeArea = routeData.DataTokens["area"] as String;
            var current = false;
    
            if (((String.IsNullOrEmpty(routeArea) && String.IsNullOrEmpty(areaName)) || (routeArea == areaName)) &&
                 ((String.IsNullOrEmpty(controllerName)) || (routeData.GetRequiredString("controller") == controllerName)) &&
                 ((actionNames == null) || actionNames.Contains(routeData.GetRequiredString("action"))))
            {
                current = true;
            }
            return current;
        }
        public static bool IsParentRoute(this RequestContext context, String controller, String action)
        {
            var routeData = context.RouteData;
            Menu returnUrl = null;
            Menu requestUrl = new Menu { Action = routeData.GetRequiredString("action"), Controller = routeData.GetRequiredString("controller") };
            Menu linkUrl = new Menu { Action = action, Controller = controller };
    
            var urls = Extention.GetDictionary();
            urls.TryGetValue(requestUrl, out returnUrl);
    
            if (returnUrl != null && returnUrl.Equals(linkUrl))
                return true;
            else
                return false; ;
        }
    }
    
    0 讨论(0)
  • 2021-02-14 16:28

    See for i.e. this URL

    http://stackoverflow.com/questions this indicates that probably the Questions Controller handles this page. So it changes the View to display a highlighted menu item.

    0 讨论(0)
提交回复
热议问题