【问题标题】:Change CSS classes from code从代码更改 CSS 类
【发布时间】:2010-10-01 13:14:00
【问题描述】:

在代码隐藏中设置CssClass 很容易,但这有覆盖现有类的风险。

我需要将某些元素设置为ReadOnly = true;,并且我想应用一种样式作为无法更改项目的视觉提示...很简单:

.CssClass += " ReadOnlyStyle";

但有时我需要将相同的元素更改为ReadOnly = false;,这意味着我需要删除我设置的 CSS 类而不删除我可能分配的任何其他样式.

最好的方法是什么?

【问题讨论】:

    标签: c# css asp.net webforms


    【解决方案1】:

    我采用了 AnthonyWJones 的原始代码并对其进行了修改,以便在任何情况下都能正常工作:

    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();
            }
        }
    

    【讨论】:

    • 通过从 split/manipulate/join 代码中提取一个方法并使用 control.Attributes("class") 而不是 control.CssClassthis HtmlControl control 创建第二个扩展方法,您可以将此功能扩展到通用 HTML 控件已将 runat="server" 添加到其中。
    • 如果AddCssClass() 在已经包含该类的字符串上被调用,这将向列表中添加一个重复的类。
    • 看起来你只想要string.Join而不是定义ToDelimitedString
    • 对于所有答案,HTML living standard 表示类属性是一组以空格分隔的标记,其中空格字符为 U+0020 SPACE、U+0009 CHARACTER TABULATION (tab)、U+000A LINE进纸 (LF)、U+000C 进纸 (FF) 和 U+000D 回车 (CR)。
    【解决方案2】:

    在 C# 3 中,您可以添加一些扩展方法。

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

    用法:-

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

    请注意,RemoveCssClass 旨在仅删除由 AddCssClass 添加的那些类,并且具有以下限制:添加 2 个附加类名称时,最短名称不应与最长名称的开头完全匹配。例如,如果您添加了“test”和“test2”,则无法在不破坏 CssClass 的情况下删除测试。这可以通过 RegEx 改进,因为我希望以上内容足以满足您的需求。

    请注意,如果您没有 C#3,请从第一个参数中删除 this 关键字,并以常规方式使用静态方法。

    【讨论】:

    • 如果要删除原始 CSS 样式,RemoveCssClass 将不起作用。
    • @John:确实如此,我确实提到“RemoveCssClass 旨在仅删除 AddCssClass 添加的那些类”。
    • 公平竞争 我确实略过了你的其余文字。
    • 为什么我应该只使用一行代码而不是使用它们的内容?什么是利益?您的方法也有使用限制(如您所述)。
    【解决方案3】:

    相关...如果您只想根据条件切换类...

    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 );
    

    【讨论】:

      【解决方案4】:

      此版本会检查以确保在添加之前尚未添加给定的类。

      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();
      }
      

      【讨论】:

        【解决方案5】:

        我为 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();
                }
            }
        

        像这样使用:

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

        这个只会添加一个类,如果它还没有。它还将删除一个类的所有实例(如果由于某种原因,那里有多个)

        【讨论】:

          【解决方案6】:

          纯 .NET 2.0(没有扩展!没有 LINQ!没有 RegEx!没有不必要的 WebControl 类!)。 这些方法非常通用,不仅仅用于 CSS 类。

          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;
              }
          

          【讨论】:

            【解决方案7】:

            您可以制作自己的自定义类吗?从 ASP.NET 按钮派生并添加只读属性。某处...可能在 OnPreRender 中,您可以检查新属性并相应地设置(或不设置)CSSClass 属性。

            【讨论】:

              猜你喜欢
              • 2016-06-05
              • 2010-09-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多