2009-01-15 16 views
5

Es fácil establecer CssClass en el código subyacente, pero esto corre el riesgo de sobrescribir las clases existentes.Cambiar clases CSS desde el código

que necesite configurar ciertos elementos de ReadOnly = true; y me gustaría aplicar un estilo como una indicación visual de que el artículo no puede ser alterado ... bastante fácil:

.CssClass += " ReadOnlyStyle"; 

Pero a veces lo haré también necesita cambiar el mismo elemento a ReadOnly = false; lo que significa que tendré que eliminar la clase de CSS que configuré sin eliminar ningún otro estilo que podría haber asignado.

¿Cuál es la mejor manera de hacerlo?

Respuesta

14

que he tomado AnthonyWJones código original y modificado para que funcione sin importar qué escenario:

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

excelente, gracias – nailitdown

+2

Al extraer un método del código split/manipular/unir y crear un segundo método de extensión para 'este control HtmlControl' usando' control.Attributes ("clase") 'en lugar de' control.CssClass', puede amplíe esta capacidad a los controles HTML genéricos que tienen runat = "server" agregado a ellos también. – patridge

+2

Esto agregará una clase duplicada a la lista si se llama a 'AddCssClass()' en una cadena que ya contiene esa clase. –

0

¿Puede hacer sus propias clases personalizadas? Derive del botón ASP.NET y agregue un propert para solo lectura. En algún lugar ... probablemente en OnPreRender, puede verificar la nueva propiedad y establecer (o no establecer) la propiedad CSSClass en consecuencia.

8

En C# 3 puede agregar algunos métodos de extensión.

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

Uso: -

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

Nota del RemoveCssClass está diseñado para eliminar sólo aquellas clases añadidas por AddCssClass y tiene la limitación de que cuando se añade 2 nombres de clases adicionales el nombre más corto no debe coincidir exactamente con el comienzo del nombre más largo. Por ejemplo, si agregó "prueba" y "prueba2", no puede eliminar la prueba sin corromper la clase CssClass. Esto podría mejorarse con RegEx por lo que espero que lo anterior sea adecuado para sus necesidades.

Tenga en cuenta que si no tiene C# 3, elimine la palabra clave this del primer parámetro y utilice los métodos estáticos de la manera convencional.

+1

RemoveCssClass no funcionará si está eliminando el estilo CSS original. –

+0

@John: Bastante y aludí a eso "RemoveCssClass está diseñado para eliminar solo las clases agregadas por AddCssClass". – AnthonyWJones

+0

Fair play Lo hice por encima del resto del texto. –

1

Esta versión comprobaciones para asegurarse de que la clase dada no se ha agregado antes de añadirla.

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

Hice una versión de 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(); 
     } 
    } 

Se utiliza como:

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

Ésta sólo se sumará una clase si no está ya allí. También eliminará todas las instancias de una clase (si, por alguna razón, hay múltiples allí)

1

Pure .NET 2.0 (¡Sin extensiones! No LINQ! No RegEx! ¡No hay clase innecesaria de WebControl!). Estos métodos son bastante generales para ser utilizados no solo para clases de CSS.

Además, mira mi 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

Relacionado ... si solo desea activar una clase según una condición ...

bool disable = true;  // this will vary (true/false) based on UI state 

string newClass = disable ? "BtnGray" : "BtnPink"; 

string currentClass = disable ? "BtnPink" : "BtnGray"; 

myButton.CssClass = myButton.CssClass.Replace(currentClass, newClass); 
Cuestiones relacionadas