1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
public static void CssAddClass(this Control control, string className) { if (control == null) { throw new ArgumentNullException("control"); } if (className == null) { throw new ArgumentNullException("className"); } string classAttributeValue; if (control is WebControl) { classAttributeValue = (control as WebControl).CssClass; } else if (control is HtmlControl) { classAttributeValue = (control as HtmlControl).Attributes["class"]; } else { throw new ArgumentException ("Must be WebControl or HtmlControl.", "control"); } if (string.IsNullOrEmpty(classAttributeValue)) { classAttributeValue = className; } else { var classNameList = classAttributeValue.Split (new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (classNameList.Contains(className)) { return; } classAttributeValue = string.Concat (classNameList.Select(name => name + " ").ToArray()) + className; } if (control is WebControl) { (control as WebControl).CssClass = classAttributeValue; } else if (control is HtmlControl) { (control as HtmlControl).Attributes["class"] = classAttributeValue; } } public static void CssRemoveClass (this Control control, string className, bool mayNotExist) { if (control == null) { throw new ArgumentNullException("control"); } if (className == null) { throw new ArgumentNullException("className"); } string classAttributeValue; if (control is WebControl) { classAttributeValue = (control as WebControl).CssClass; } else if (control is HtmlControl) { classAttributeValue = (control as HtmlControl).Attributes["class"]; } else { throw new ArgumentException ("Must be WebControl or HtmlControl.", "control"); } bool isNullOrEmpty = string.IsNullOrEmpty(classAttributeValue); if (!mayNotExist && isNullOrEmpty) { throw new ArgumentException ("Does not have any CSS classes defined.", className); } else if (isNullOrEmpty) { classAttributeValue = string.Empty; } var classNames = from name in classAttributeValue.Split (new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) where name != className select name + " "; classAttributeValue = string.Concat(classNames.ToArray()).TrimEnd(); if (control is WebControl) { (control as WebControl).CssClass = classAttributeValue; } else if (control is HtmlControl) { (control as HtmlControl).Attributes["class"] = classAttributeValue; } }
Refactorings
No refactoring yet !
Dizzle
May 2, 2009, May 02, 2009 23:14, permalink
I don't understand what you're trying to accomplish. Are you attempting to code infinity around control.CssClass = "class-name" ?
Ants
May 3, 2009, May 03, 2009 03:12, permalink
Try applying some DRY principles... Now if somebody could refactor the Get/SetCssClass() methods below to be even DRY-er.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
static string GetCssClass(Control control) { if (control == null) throw new ArgumentNullException("control"); WebControl web = control as WebControl; HtmlControl html = control as HtmlControl; if (web != null) return web.CssClass; else if (html != null) return html.Attributes["class"]; throw new ArgumentException("Must be WebControl or HtmlControl.", "control"); } static void SetCssClass(Control control, string classAttributeValue) { if (control == null) throw new ArgumentNullException("control"); WebControl web = control as WebControl; HtmlControl html = control as HtmlControl; if (web != null) web.CssClass = classAttributeValue; else if (html != null) html.Attributes["class"] = classAttributeValue; throw new ArgumentException("Must be WebControl or HtmlControl.", "control"); } static void SetCssClass(Control control, List<string> classNameList) { SetCssClass(control, String.Join(" ", classNameList.ToArray())); } static List<string> GetClassNames(string classAttributeValue) { if (String.IsNullOrEmpty(classAttributeValue)) return new List<string>(); return new List<string>(classAttributeValue.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); } static void ValidateClassNameArg(string className) { if (className == null) throw new ArgumentNullException("className"); else if (className == String.Empty) throw new ArgumentException("className cannot be empty", "className"); } public static void CssAddClass(this Control control, string className) { ValidateClassNameArg(className); var classNameList = GetClassNames(GetCssClass(control)); if (!classNameList.Contains(className)) { classNameList.Add(className); SetCssClass(control, classNameList); } } public static void CssRemoveClass (this Control control, string className, bool mayNotExist) { ValidateClassNameArg(className); var classNameList = GetClassNames(GetCssClass(control)); if (!mayNotExist && classNameList.Count == 0) throw new ArgumentException("Does not have any CSS classes defined.", className); if (classNameList.Remove(className)) SetCssClass(control, classNameList); }
Ants
May 4, 2009, May 04, 2009 07:32, permalink
In an attempt to make things DRY-er, I came up with this second refactoring to apply a strategy pattern to try to encapsulate the knowledge of how to get/set the appropriate control properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
static class CssClassExtensions { struct GetSet { public Func<object, string> Get; public Action<object, string> Set; } static Dictionary<Type, GetSet> s_getsets = new Dictionary<Type, GetSet>(); static void Register<T>(Func<T, string> getter, Action<T, string> setter) { s_getsets.Add(typeof(T), new GetSet() { Get = o => getter((T) o), Set = (o, s) => setter((T) o, s) }); } static CssClassExtensions() { Register<WebControl>(web => web.CssClass, (web, s) => web.CssClass = s); Register<HtmlControl>(html => html.Attributes["class"], (html, s) => html.Attributes["class"] = s); } static GetSet FindGetSet(Control control) { if (control == null) throw new ArgumentNullException("control"); foreach (Type type in s_getsets.Keys) { if (type.IsInstanceOfType(control)) return s_getsets[type]; } throw new ArgumentException(String.Format("No registered CSS class accessor for {0}.", control.GetType()), "control"); } static string GetCssClass(Control control) { return FindGetSet(control).Get(control); } static void SetCssClass(Control control, string classAttributeValue) { FindGetSet(control).Set(control, classAttributeValue); } static void SetCssClass(Control control, List<string> classNameList) { SetCssClass(control, String.Join(" ", classNameList.ToArray())); } static List<string> GetClassNames(string classAttributeValue) { if (String.IsNullOrEmpty(classAttributeValue)) return new List<string>(); return new List<string>(classAttributeValue.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); } static void ValidateClassNameArg(string className) { if (className == null) throw new ArgumentNullException("className"); else if (className == String.Empty) throw new ArgumentException("className cannot be empty", "className"); } public static void CssAddClass(this Control control, string className) { ValidateClassNameArg(className); var classNameList = GetClassNames(GetCssClass(control)); if (!classNameList.Contains(className)) { classNameList.Add(className); SetCssClass(control, classNameList); } } public static void CssRemoveClass (this Control control, string className, bool mayNotExist) { ValidateClassNameArg(className); var classNameList = GetClassNames(GetCssClass(control)); if (!mayNotExist && classNameList.Count == 0) throw new ArgumentException("Does not have any CSS classes defined.", className); if (classNameList.Remove(className)) SetCssClass(control, classNameList); } }
Have at it.