2012-02-15 17 views
14

ASP.NET MVC 3を使用しているときに、ナビゲーションの現在のページにCSSクラスを追加することはどうすればできますか?あなたは私がそれに適用される「現在」のCSSクラスを有する第1と私のナビゲーションで4つのリンクを持って見ることができるように、私はなりたいASP.NET MVC - ナビゲーションでの現在のページの強調表示

<p>@Html.ActionLink("Product Search", "Index", new { controller = "Home" }, new { @class = "current" }) 
       | @Html.ActionLink("Orders", "Index", new { controller = "Orders" }) 
       | @Html.ActionLink("My Account", "MyAccount", new { controller = "Account" }) 
       | @Html.ActionLink("Logout", "LogOff", new { controller = "Account" })</p> 

:ここに私のナビゲーションは、私の_Layout.cshtmlファイルでありますユーザーがどのページにいるかに応じて、ナビゲーション内のさまざまなリンクにこのクラスを追加/削除することができます。これは可能ですか?あなたが行うことができ、あなたのHTMLであなたのclass属性に続いて、この

@{ 
    var currentController = ViewContext.RouteData.Values["controller"] as string ?? "Home"; 
    var currentAction = ViewContext.RouteData.Values["action"] as string ?? "Index"; 
    var currentPage = (currentController + "-" + currentAction).ToLower(); 
} 

@Html.ActionLink("Product Search", "Index", "Home", null, 
       new { @class = currentPage == "home-index" ? "current" : "" }) 
@Html.ActionLink("MyAccount", "MyAccount", "Account", null, 
        new { @class = currentPage == "account-myaccount" ? "current" : "" }) 

答えて

12

をとります。

public static HtmlString NavigationLink(
    this HtmlHelper html, 
    string linkText, 
    string actionName, 
    string controllerName) 
{ 
    string contextAction = (string)html.ViewContext.RouteData.Values["action"]; 
    string contextController = (string)html.ViewContext.RouteData.Values["controller"]; 

    bool isCurrent = 
     string.Equals(contextAction, actionName, StringComparison.CurrentCultureIgnoreCase) && 
     string.Equals(contextController, controllerName, StringComparison.CurrentCultureIgnoreCase); 

    return html.ActionLink(
     linkText, 
     actionName, 
     controllerName, 
     routeValues: null, 
     htmlAttributes: isCurrent ? new { @class = "current" } : null); 
} 

次に、あなたがあなたの拡張機能の名前空間を含め、ちょうどあなたのメソッドを呼び出すことによって、あなたのビューでそれを使用することができます:ような何か

@using MyExtensionNamespace; 

... 

    @Html.NavigationLink("Product Search", "Index", "Home") 
| @Html.NavigationLink("Orders", "Index", "Orders") 
| @Html.NavigationLink("My Account", "MyAccount", "Account") 
| @Html.NavigationLink("Logout", "LogOff", "Account") 

これは少しクリーナーあなたのかみそりを維持するという利点を持っており、他のビューでも簡単に再利用できます。

+0

これが最良の方法だと感じているので、答えがマークされています。きれいなかみそりの表示とコードの再利用性 – CallumVass

+0

拡張子 'HtmlHelper.ActionLink()'に対して、次のように[LinkExtensions](https://msdn.microsoft.com/en-us/library/system.web.mvc.html.linkextensions.aspx)の名前空間を追加します。 'using System.Web.Mvc.Html;' – Mike

24

:@dknaack彼の

class="@isActiveController("controlername","action","activecssstyleclass","inactiveccsstyle")" 

ただ、他の方法答え...より一般的で、コード内で繰り返す機能が少なくなりました。

+0

感謝を!これは役に立ちました – CallumVass

+0

喜んで助けてください!良い一日を! – dknaack

+0

@dknaackあなたは最後の前にa}が欠けていませんか? –

8
@{ 
    var controller = ViewContext.RouteData.Values["controller"].ToString(); 
    var action = ViewContext.RouteData.Values["action"].ToString(); 
    var isActiveController = new Func<string, string, string, string, string>((ctrl, act, activeStyle, inactiveStyle) => controller == ctrl && action == act ? activeStyle : inactiveStyle); 
} 

を行うことができます

乾杯

2

私はこれを成し遂げるために、このチュートリアルを使用し、それは理解することがずっと簡単だと私は、このための拡張メソッドを使用することをお勧めします2分 Hightlight Active menu item

+1

このアプローチの欠点は、それぞれのコントローラのアクションでViewBag.CurrentPageを実行する必要があることです。 – CallumVass

2

私の場合、ホームページとメニューがあるとします。

は、このようなホーム・ページ内のプレースホルダとしてViewBag.Activeを追加します。

@{ 
    ViewBag.Title = "Home"; 
    ViewBag.Active = "Home"; 
} 

を次にアクティブかどうかの条件としてごliクラスにそれを置く:

<li class="@(ViewBag.Active=="Home"? "active" : "")"> 
     <a href="@Url.Action("Index", "Home")"><span>@ViewBag.Title</span></a> 
</li> 
+0

私は本当にこの答えが好きです。簡単で実用的です。 –

+0

これは、ブートストラップ4のnavセットアップでうまく動作します。ここで、liには "アクティブ" CSSクラスと "nav-item" – JaneH

関連する問題