2009-01-15 19 views
5

Łatwo jest ustawić CssClass w kodzie z tyłu, ale wiąże się to z ryzykiem nadpisania istniejących klas.Zmiana klas CSS z kodu

muszę ustawić pewne elementy do ReadOnly = true; i chciałabym zastosować styl jako wizualnego wskaźnika, że ​​przedmiot nie może być zmieniona ... dość proste:

.CssClass += " ReadOnlyStyle"; 

Ale czasami będę również trzeba zmienić ten sam element na ReadOnly = false; co oznacza, że ​​będę musiał usunąć ustawioną klasę CSS bez usuwania jakichkolwiek innych stylów, które mogłem przypisać.

Jaki jest najlepszy sposób na zrobienie tego?

Odpowiedz

14

Wziąłem AnthonyWJones oryginalny kod i wprowadza go tak, że działa bez względu na scenariusz:

static class WebControlsExtensions 
    { 
     public static void AddCssClass(this WebControl control, string cssClass) 
     { 
      List<string> classes = control.CssClass.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList(); 

      classes.Add(cssClass); 

      control.CssClass = classes.ToDelimitedString(" "); 
     } 

     public static void RemoveCssClass(this WebControl control, string cssClass) 
     { 
      List<string> classes = control.CssClass.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList(); 

      classes.Remove(cssClass); 

      control.CssClass = classes.ToDelimitedString(" "); 
     } 
    } 

    static class StringExtensions 
    { 
     public static string ToDelimitedString(this IEnumerable<string> list, string delimiter) 
     { 
      StringBuilder sb = new StringBuilder(); 
      foreach (string item in list) 
      { 
       if (sb.Length > 0) 
        sb.Append(delimiter); 

       sb.Append(item); 
      } 

      return sb.ToString(); 
     } 
    } 
+0

doskonałe, dzięki – nailitdown

+2

Wyodrębniając metodę z kodu podziału/manipulowania/łączenia i tworząc drugą metodę rozszerzenia dla 'tego kontrolka HtmlControl' za pomocą' control.Attributes ("class") 'zamiast' control.CssClass', możesz rozszerz tę zdolność na ogólne kontrolki HTML, które mają również runat = "server". – patridge

+2

Spowoduje to dodanie do listy zduplikowanych klas, jeśli '' AddCssClass() 'zostanie wywołana w ciągu, który już zawiera tę klasę. –

0

Czy możesz tworzyć własne niestandardowe klasy? Wyprowadź z przycisku ASP.NET i dodaj element własności tylko do odczytu. Gdzieś ... prawdopodobnie w OnPreRender możesz sprawdzić nową właściwość i odpowiednio ustawić (lub nie ustawić) właściwość CSSClass.

8

W C# 3 możesz dodać kilka metod rozszerzenia.

static class WebControlsExtensions 
{ 
    public static void AddCssClass (this WebControl control, string cssClass) 
    { 
     control.CssClass += " " + cssClass; 
    } 
    public static void RemoveCssClass (this WebControl control, string cssClass) 
    { 
     control.CssClass = control.CssClass.replace(" " + cssClass, ""); 
    } 
} 

Zastosowanie: -

ctl.AddCssClass("ReadOnly"); 
ctl.RemoveCssClass("ReadOnly"); 

Zanotuj RemoveCssClass jest przeznaczona do usunięcia tylko te zajęcia dodane przez AddCssClass i ma ograniczenie, że gdzie 2 dodatkowe nazwy klasy dodaje najkrótsza nazwa nie powinna dokładnie odpowiadać początek najdłuższej nazwy. Np. Jeśli dodano "test" i "test2", nie można usunąć testu bez uszkodzenia klasy CssClass. Można to poprawić dzięki RegEx przez Oczekuję, że powyższe będzie odpowiednie do twoich potrzeb.

Uwaga, jeśli nie masz C# 3, usuń słowo kluczowe this z pierwszego parametru i użyj metod statycznych w konwencjonalny sposób.

+1

Polecenie RemoveCssClass nie działa, jeśli usuwasz oryginalny styl CSS. –

+0

@John: Całkiem tak, a ja nawiązywałem do tego, że "RemoveCssClass jest przeznaczony do usuwania tylko tych klas dodanych przez AddCssClass". – AnthonyWJones

+0

Fair play Przeszedłem przez resztę tekstu. –

1

Wersja ta sprawdza, czy dana klasa nie jest już dodane przed dodaniem go.

public static void CssAddClass(this WebControl control, string className) 
{ 
    var classNames = control.CssClass.Split 
     (new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 

    if (classNames.Contains(className)) 
    { 
     return; 
    } 

    control.CssClass = string.Concat 
     (classNames.Select(name => name + " ").ToArray()) + className; 
} 

public static void CssRemoveClass(this WebControl control, string className) 
{ 
    var classNames = from name in control.CssClass. 
         Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries) 
        where name != className 
        select name + " "; 


    control.CssClass = string.Concat(classNames.ToArray()).TrimEnd(); 
} 
1

zrobiłem wersję dla pre-C# 3:

 public static class WebControlsExtensions 
     { 
      public static void AddCssClass(WebControl control, string cssClass) 
      { 
       string[] cssClasses = control.CssClass.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 
       List<string> classes = new List<string>(cssClasses); 

       if (!classes.Contains(cssClass)) { 
        classes.Add(cssClass); 
       } 

       control.CssClass = StringExtensions.ToDelimitedString(classes, " "); 
      } 

      public static void RemoveCssClass(WebControl control, string cssClass) 
      { 
       string[] cssClasses = control.CssClass.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 
       List<string> classes = new List<string>(cssClasses); 

       bool removed = true; 
       while (removed) { 
        removed = classes.Remove(cssClass); 
       } 

       control.CssClass = StringExtensions.ToDelimitedString(classes, " "); 
      } 
    } 
    static class StringExtensions { 
     public static string ToDelimitedString(List<string> list, string delimiter) 
     { 
      StringBuilder sb = new StringBuilder(); 
      foreach (string item in list) { 
       if (sb.Length > 0) 
        sb.Append(delimiter); 

       sb.Append(item); 
      } 

      return sb.ToString(); 
     } 
    } 

używane jak:

WebControlsExtensions.AddCssClass(ctl, "classname"); 
WebControlsExtensions.RemoveCssClass(ctl, "classname"); 

Ten jeden tylko dodać klasę, jeśli nie jest już tam. Spowoduje to również usunięcie wszystkich wystąpień klasy (jeśli z jakiegoś powodu jest tam wiele):

1

Pure. NET 2.0 (brak rozszerzeń! Brak LINQ! Brak RegEx! Brak niepotrzebnej klasy WebControl!). Metody te są dość ogólne, aby można je było używać nie tylko w klasach CSS.

Zobacz także mój CssClassManipulator.

public static string AddCssClass(string classContainer, string className) 
    { 
     if (string.IsNullOrEmpty(classContainer)) return className ?? string.Empty; 
     if (string.IsNullOrEmpty(className)) return classContainer; 

     var classNames = classContainer.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 
     if (Array.Exists(classNames, delegate(string s) { return s.Equals(className); })) return classContainer; 

     return classContainer + " " + className; 
    } 

    public static string RemoveCssClass(string classContainer, string className) 
    { 
     if (string.IsNullOrEmpty(classContainer)) return className ?? string.Empty; 
     if (string.IsNullOrEmpty(className)) return classContainer; 

     var classNames = classContainer.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 
     int index = Array.FindIndex(classNames, delegate(string s) { return s.Equals(className); }); 
     if (index >= 0) 
     { 
      return string.Join(" ", classNames, 0, index) + 
       ( index + 1 < classNames.Length ? 
        " " + string.Join(" ", classNames, index + 1, classNames.Length - index - 1) 
        : 
        string.Empty ); 
     } 

     return classContainer; 
    } 

    public static string ToggleCssClass(string classContainer, string className) 
    { 
     if (string.IsNullOrEmpty(classContainer)) return className ?? string.Empty; 
     if (string.IsNullOrEmpty(className)) return classContainer; 

     var classNames = classContainer.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 

     if (Array.Exists(classNames, delegate(string s) { return s.Equals(className); })) return RemoveCssClass(classContainer, className); 

     return classContainer + " " + className; 
    } 
2

Powiązane ... jeśli chcesz przełączyć klasę na podstawie warunku ...