No Bootstrap, a active
classe precisa ser aplicada ao <li>
elemento e não ao <a>
. Veja o primeiro exemplo aqui: http://getbootstrap.com/components/#navbar
A maneira como você lida com o estilo da interface do usuário com base no que está ativo ou não tem nada a ver com o ActionLink
assistente do ASP.NET MVC . Esta é a solução adequada para acompanhar como a estrutura do Bootstrap foi criada.
<ul class="nav navbar-nav">
<li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
Editar:
Como você provavelmente estará reutilizando seu menu em várias páginas, seria inteligente aplicar uma classe selecionada automaticamente com base na página atual, em vez de copiar o menu várias vezes e fazê-lo manualmente.
A maneira mais fácil é usar apenas os valores contidos em ViewContext.RouteData
, ou seja, os Action
e Controller
valores. Podemos desenvolver o que você tem atualmente com algo assim:
<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
Não é bonito no código, mas fará o trabalho e permitirá que você extraia seu menu em uma exibição parcial, se quiser. Existem maneiras de fazer isso de uma maneira muito mais limpa, mas como você está apenas começando, deixarei por isso. Boa sorte ao aprender o ASP.NET MVC!
Edição tardia:
Esta questão parece estar recebendo um pouco de tráfego, então imaginei que lançaria uma solução mais elegante usando uma HtmlHelper
extensão.
Editar 24-03-2015: tive que reescrever esse método para permitir várias ações e controladores acionando o comportamento selecionado, além de lidar com quando o método é chamado a partir de uma exibição parcial de ação filho, pensei em compartilhar a atualização!
public static string IsSelected(this HtmlHelper html, string controllers = "", string actions = "", string cssClass = "selected")
{
ViewContext viewContext = html.ViewContext;
bool isChildAction = viewContext.Controller.ControllerContext.IsChildAction;
if (isChildAction)
viewContext = html.ViewContext.ParentActionViewContext;
RouteValueDictionary routeValues = viewContext.RouteData.Values;
string currentAction = routeValues["action"].ToString();
string currentController = routeValues["controller"].ToString();
if (String.IsNullOrEmpty(actions))
actions = currentAction;
if (String.IsNullOrEmpty(controllers))
controllers = currentController;
string[] acceptedActions = actions.Trim().Split(',').Distinct().ToArray();
string[] acceptedControllers = controllers.Trim().Split(',').Distinct().ToArray();
return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
cssClass : String.Empty;
}
Funciona com o .NET Core:
public static string IsSelected(this IHtmlHelper htmlHelper, string controllers, string actions, string cssClass = "selected")
{
string currentAction = htmlHelper.ViewContext.RouteData.Values["action"] as string;
string currentController = htmlHelper.ViewContext.RouteData.Values["controller"] as string;
IEnumerable<string> acceptedActions = (actions ?? currentAction).Split(',');
IEnumerable<string> acceptedControllers = (controllers ?? currentController).Split(',');
return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
cssClass : String.Empty;
}
Uso da amostra:
<ul>
<li class="@Html.IsSelected(actions: "Home", controllers: "Default")">
<a href="@Url.Action("Home", "Default")">Home</a>
</li>
<li class="@Html.IsSelected(actions: "List,Detail", controllers: "Default")">
<a href="@Url.Action("List", "Default")">List</a>
</li>
</ul>