2009-09-24 51 views
17

作爲討論的基礎。創建一個標準的ASP.NET MVC Web項目。如何在ASP.NET MVC中直觀地表示當前頁面?

它將包含在母版頁兩個菜單項:

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

如何設置指示當前頁面的可視化CSS樣式。 例如,在關於頁/控制器,我基本上是想做到這一點:

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

,當然,在主頁上:

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

(有一個CSS樣式在當前頁面上顯示當前菜單中顯示的名稱)

我可以將菜單div從主頁面分解爲內容佔位符,但這意味着我必須將菜單放在每個頁面上。

任何想法,有沒有一個很好的解決方案呢?

回答

24

最簡單的方法是讓從ViewContext的的RouteData電流控制器和行動。請注意簽名的更改和使用@來轉義關鍵字。

<% 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" : "") %> 

請注意,您可以將這個HtmlHelper擴展名組合爲@Jon's並使其更加清晰。

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

哪裏MenuActionLink是

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); 
    } 
} 
+0

不是一個好的解決方案。視圖應該對控制器和操作一無所知。要顯示的數據只能由模型提供。 – 2009-09-24 13:09:06

+1

這只是獲取URL的捷徑 - 您可以使用所請求的URL做同樣的事情,但是您必須解析它。我滿足於這種機制並沒有打破這種模式。 – tvanfosson 2009-09-24 13:19:55

+0

語法是否正確?我得到「不能用[]將索引應用於類型爲'System.Web.Routing'的表達式。RouteData'「 – 2009-09-24 13:33:29

0

它可能只是它的第5個參數,所以請在html屬性之前插入null。這裏這篇文章描述它是這樣,但你可以在一些東西通過四號arguement,第五是專門爲HTMLattributes

+0

@class而不是類:) – 2009-09-24 12:38:01

1

我最近創建的HTML助手這個看起來像:

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); 
} 

的實現看起來是這樣的:

<ul id="Navigation"> 
    <%=Html.NavigationLink("/Path1", "Text1")%> 
    <%=Html.NavigationLink("/Path2", "Text2")%> 
    <%=Html.NavigationLink("/Path3", "Text3")%> 
    <%=Html.NavigationLink("/Path4", "Text4")%> 
    </ul> 
+0

我有這個問題。首先,它不會解決字符串外殼問題,如果您在url中提供了不同的外殼(請記住用戶可以直接輸入這些內容)就會中斷。其次,考慮到對靜態HttpContext.Current的依賴,將很難進行單元測試。第三,如果你的動作/菜單有多個級別,則「最高」級別將匹配所有子級別。當然,我的解決方案也有第三個問題,但由於它不依賴字符串匹配,因此修改它以適應多個級別會稍微容易一些。 – tvanfosson 2009-09-24 15:19:09

+0

...我喜歡,並借用了這個想法 - 謝謝 - 使它成爲視圖代碼整潔的擴展方法的想法。 – tvanfosson 2009-09-24 15:23:31

+0

感謝您的反饋!我仍然是新手,並且一直在尋找改進我的代碼的方法。 – Jon 2009-09-24 16:18:41

1

如果你正在使用T4MVC ,您可以使用此:

 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); 
    } 
0
<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> 

在5分鐘一起打發這一點,我大概可以重構它,但應該給你的基本概念,它可能是小網站最有用的。

相關問題