How to visually indicate current page in ASP.NET M

2020-02-17 05:29发布

As a base for discussion. Create a standard ASP.NET MVC Web project.

It will contain two menu items in the master page:

<div id="menucontainer">
  <ul id="menu">
    <li>
      <%= Html.ActionLink("Home", "Index", "Home")%></li>
    <li>
      <%= Html.ActionLink("About", "About", "Home")%></li>
  </ul>
</div>

How can I set the visual CSS style indicating the current page. For example, when in the About page/controller, I essentially would like to do this:

<%= Html.ActionLink("About", "About", "Home", new {class="current"})%></li>

And, of course, when on the home page:

<%= Html.ActionLink("Home", "Index", "Home", new {class="current"})%></li>

(Having a CSS style names current that visually indicates in the menu that this is the current page.)

I could break out the menu div from the master page into a content place holder, but that would mean that I must put the menu on every page.

Any ideas, is there a nice solution to this?

5条回答
兄弟一词,经得起流年.
2楼-- · 2020-02-17 06:08

I recently created an HTML Helper for this that looks like:

public static string NavigationLink(this HtmlHelper helper, string path, string text)
{
    string cssClass = String.Empty;
    if (HttpContext.Current.Request.Path.IndexOf(path) != -1)
    {
        cssClass = "class = 'selected'";
    }

    return String.Format(@"<li><a href='{0}' {1}>{2}</a></li>", path, cssClass, text);
}

The Implementation looks like this:

  <ul id="Navigation">
  <%=Html.NavigationLink("/Path1", "Text1")%>
  <%=Html.NavigationLink("/Path2", "Text2")%>
  <%=Html.NavigationLink("/Path3", "Text3")%>
  <%=Html.NavigationLink("/Path4", "Text4")%>
  </ul>
查看更多
三岁会撩人
3楼-- · 2020-02-17 06:13

The easiest way is to get the current controller and action from the ViewContext's RouteData. Note the change in signature and use of @ to escape the keyword.

<% var controller = ViewContext.RouteData.Values["controller"] as string ?? "Home";
   var action = ViewContext.RouteData.Values["action"] as string ?? "Index";
   var page = (controller + ":" + action).ToLower();
 %>

<%= Html.ActionLink( "About", "About", "Home", null,
                     new { @class = page == "home:about" ? "current" : "" ) %>
<%= Html.ActionLink( "Home", "Index", "Home", null,
                     new { @class = page == "home:index" ? "current" : "" ) %>

Note that you could combine this an HtmlHelper extension like @Jon's and make it cleaner.

<%= Html.MenuLink( "About", "About", "Home", null, null, "current" ) %>

Where MenuActionLink is

public static class MenuHelperExtensions
{
     public static string MenuLink( this HtmlHelper helper,
                                    string text,
                                    string action,
                                    string controller,
                                    object routeValues,
                                    object htmlAttributes,
                                    string currentClass )
     {
         RouteValueDictionary attributes = new RouteValueDictionary( htmlAttributes );
         string currentController = helper.ViewContext.RouteData.Values["controller"] as string ?? "home";
         string currentAction = helper.ViewContext.RouteData.Values["action"] as string ?? "index";
         string page = string.Format( "{0}:{1}", currentController, currentAction ).ToLower();
         string thisPage = string.Format( "{0}:{1}", controller, action ).ToLower();
         attributes["class"] = (page == thisPage) ? currentClass : "";
        return helper.ActionLink( text, action, controller, new RouteValueDictionary( routeValues ), attributes );
     }
}
查看更多
够拽才男人
4楼-- · 2020-02-17 06:18

It might just be that it's the 5th parameter, so slot a null before your html attribute. This post here describes it as such, though you can pass in some stuff on the 4th arguement, the 5th is specifically for HTMLattributes

查看更多
一纸荒年 Trace。
5楼-- · 2020-02-17 06:21

If you are using T4MVC, you can use this:

        public static HtmlString MenuLink(
        this HtmlHelper helper,
        string text,
        IT4MVCActionResult action,
        object htmlAttributes = null)
    {
        var currentController = helper.ViewContext.RouteData.Values["controller"] as string ?? "home";
        var currentAction = helper.ViewContext.RouteData.Values["action"] as string ?? "index";

        var attributes = new RouteValueDictionary(htmlAttributes);
        var cssClass = (attributes.ContainsKey("class"))
                           ? attributes["class"] + " "
                           : string.Empty;

        string selectedClass;
        if(action.Controller.Equals(currentController, StringComparison.InvariantCultureIgnoreCase)
        {
            selectedClass = "selected-parent";
            if(action.Action.Equals(currentAction, StringComparison.InvariantCultureIgnoreCase))
                selectedClass = "selected";
        }
        cssClass += selectedClass;

        attributes["class"] = cssClass;

        return helper.ActionLink(text, (ActionResult)action, attributes);
    }
查看更多
男人必须洒脱
6楼-- · 2020-02-17 06:32
<script type="javascript/text">
$( document ).ready( function() {

        @if (Request.Url.AbsolutePath.ToLower() == "/") 
        {
            @Html.Raw("$('.navbar-nav li').eq(0).attr('class','active');")
        }

        @if (Request.Url.AbsolutePath.ToLower().Contains("details")) 
        {
            @Html.Raw("$('.navbar-nav li').eq(1).attr('class','active');")
        }

        @if (Request.Url.AbsolutePath.ToLower().Contains("schedule")) 
        {
            @Html.Raw("$('.navbar-nav li').eq(2).attr('class','active');")
        }

    });
</script>

Chucked this together in 5mins, I could probably refactor it, but should give you the basic idea, its probably most useful for smaller sites.

查看更多
登录 后发表回答