ASP.NET MVC Динамически устанавливает класс CSS для элемента списка на основе маршрута - PullRequest
3 голосов
/ 27 июня 2010

Я смотрю на веб-сайт StackOverflow и заметил, что для кнопок активных видов установлен атрибут Class="youarehere". В результате получается оранжевый стиль вместо серого.

Кто-нибудь может сказать мне, как они это делают? Какой самый простой способ динамически установить класс на основе URL-адреса?

Ответы [ 5 ]

5 голосов
/ 27 июня 2010

Написание html-помощника для этих кнопок может быть одним из способов сделать это.Предполагая, что стандартная маршрутизация установлена:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

, вот как может выглядеть помощник:

public static MvcHtmlString MyButton(this HtmlHelper htmlHelper, string id, string text)
{
    var button = new TagBuilder("input");
    button.MergeAttribute("type", "button");
    button.MergeAttribute("value", text);
    // get the id from the current route:
    var routeId = htmlHelper.ViewContext.RouteData.Values["id"] as string;
    if (id == routeId)
    {
        button.MergeAttribute("class", "active");
    }
    return MvcHtmlString.Create(button.ToString(TagRenderMode.SelfClosing));
}

и, наконец, добавьте к вашему виду:

<%= Html.MyButton("questions", "Questions") %>
<%= Html.MyButton("tags", "Tags") %>
<%= Html.MyButton("users", "Users") %>

ToДля дальнейшего улучшения помощника вы можете добавить дополнительные параметры, которые будут содержать действие, и контроллер, на который эта кнопка будет перенаправляться при нажатии.

0 голосов
/ 01 апреля 2013

вы можете создать HtmlHelper для возврата значения, чтобы вы могли использовать его где угодно

Создать папку «HtmlHelpers» в вашем проекте Создать статический класс Определите статический метод с помощью первого параметра «this HtmlHelper»helper «

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

namespace ThisMVCApp.WebUI.HtmlHelpers
{
  public static class HtmlHelperExtensions
  {
    public static string IfActive(this HtmlHelper helper, string controller, string action)
    {
      string classValue = "";

      string currentController = helper.ViewContext.Controller.ValueProvider.GetValue("controller").RawValue.ToString();
      string currentAction = helper.ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();

      if (currentController == controller && currentAction == action)
      {
        classValue = "youarehere";
      }

      return classValue;
    }
  }
}

Добавьте это в свой файл web.config (тот, что находится в вашей папке Views!)

<system.web.webPages.razor>
  <host ... />
  <pages pageBaseType="System.Web.Mvc.WebViewPage">
    <namespaces>
      ...
      <add namespace="ThisMVCApp.WebUI.HtmlHelpers" />
    </namespaces>
  </pages>
</system.web.webPages.razor>

, теперь вы можете просто применить вышеуказанный метод как любой класс илиатрибут на кнопках или любом другом элементе, подобном так:

<nav>
  <ul id="menu">
    <li class="@Html.IfActive("Home", "Index")">@Html.ActionLink("Home", "Index", "Home")</li>
    <li class="@Html.IfActive("Home", "About")">@Html.ActionLink("About", "About", "Home")</li>
 </ul>
</nav>
0 голосов
/ 28 июня 2010

Вот ответ, который мне нужен (в VB). Спасибо @ Darin

Imports System.Web.Mvc
Imports System.Web.Mvc.Html

Namespace Utilities.HtmlHelpers
    Public Module PagingHelpers
        Sub New()
        End Sub

        <System.Runtime.CompilerServices.Extension()> _
        Public Function CustomLink( _
                ByVal htmlHelper As HtmlHelper, _
                ByVal linkText As String, _
                ByVal actionName As String, _
                ByVal controllerName As String) As MvcHtmlString


            Dim currentAction As String = TryCast(htmlHelper.ViewContext.RouteData.Values.Item("action"), String)
            Dim currentController As String = TryCast(htmlHelper.ViewContext.RouteData.Values.Item("controller"), String)
            If ((actionName = currentAction) AndAlso _
                (controllerName = currentController)) Or _
                ((controllerName = currentController) AndAlso _
                Not controllerName = "Events") Then
                Return htmlHelper.ActionLink( _
                    linkText, _
                    actionName, _
                    controllerName, _
                    Nothing, _
                    New With { _
                        .class = "youarehere" _
                    })
            End If
            Return htmlHelper.ActionLink(linkText, actionName, controllerName)
        End Function
    End Module

End Namespace
0 голосов
/ 27 июня 2010

У меня есть альтернативное решение. Вместо того, чтобы вспомогательный класс решал, какое «меню» является активным меню. Решите, что в действии вашего контроллера.

Ваш контроллер

public ActionView Questions()
{
    MyViewModel model = new MyViewModel ();
    model.CurrentMenu = "Questions"; 
    ViewData.Model = model;
}

public ActionView Tags()
{
    MyViewModel model = new MyViewModel ();
    model.CurrentMenu = "Tags"; 
    ViewData.Model = model;
}

В представлении (строго типизированное представление)

<div id="menu">    
    <ul>
    <li class="<%= Html.IsSelectedMenu(Model.CurrentMenu,'Questions') %>"<a href="/Home/Questions">Questions</a></li> 
    <li class="<%= Html.IsSelectedMenu(Model.CurrentMenu,'Tags') %>"<a href="/Home/Tags">Tags</a></li> 
    </ul>
</div>    

В вашем css

li.youarehere
{
    background-color: orange;
    color: #ffffff;
}

В вашем классе помощников

public static class MyHtmlExtensions
{
    public static MvcHtmlString IsSelectedMenu(this HtmlHelper helper, string currentMenu, string menu2)
    {
        return currentMenu.Equals (menu2)? "youarehere" : "";
    }
}
0 голосов
/ 27 июня 2010

Я бы предположил, что самый простой из возможных способов - поместить информацию в ViewData из контроллера / действия, сообщая представлению, где оно находится, и это то, что я делаю.

В представлении вы получите этоданные из ViewData, а затем выяснить, какое имя класса связать с каким местоположением.Обязательно используйте помощник HTML.

Действие под контроллером вопросов:

public ActionResult Index()
{
      ViewData["CurrentPage"] = "Questions";
}

Помощник HTML:

public static string GetLocationCssClassName(this HtmlHelper html)
{
         string cssClass = string.Empty;
         if(html.ViewData["CurrentPage"] != null)
         {
             string currentPage = (string)html.ViewData["CurrentPage"];
             switch(currentPage)
             { 
                 case "Questions":
                       cssClass = "question_css_class";
                       break;
                 case "Tags":
                       cssClass = "tags_css_class";
                       break;
                 case "Users":
                       cssClass = "users_css_class";
                       break;

             }
         }
         return cssClass;
}

Просмотр страницы:

<div id="main" class="<%: Html.GetLocationCssClassName() %>">

   <a href="Questions/Index" class="questions">Questions</a>
   <a href="Tags/Index" class="tags">Tags</a>
   <a href="Users/Index" class="users">Users</a>

</div>

Css:

.question_css_class a.questions
{
    background-color: Orange;
}

Код можно бесконечно улучшать, но вы получите суть.Ваш вид имеет доступ к ViewData.Назначьте определенный ключ, который будет содержать текущую страницу, и вывести соответствующий класс на основе значения внутри этого конкретного ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...