/// /// 顏色擴展類 /// public static class ColorExtensions { /// /// .NET預定義的系統顏色緩存列表 /// private static readonly Dictionary ColorCache; /// /// 擁有相同顏色代碼值的... ...
/// <summary> /// 顏色擴展類 /// </summary> public static class ColorExtensions { /// <summary> /// .NET預定義的系統顏色緩存列表 /// </summary> private static readonly Dictionary<int, Color> ColorCache; /// <summary> /// 擁有相同顏色代碼值的系統顏色名稱列表 /// </summary> private static readonly Dictionary<int, string[]> DuplicateColorNameCache; /// <summary> /// 靜態構造函數 /// </summary> static ColorExtensions() { ColorCache = new Dictionary<int, Color>(); DuplicateColorNameCache = new Dictionary<int, string[]>(); Type type = typeof(Color); var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase); foreach (var propertyInfo in properties) { var value = propertyInfo.GetValue(null, null); if (value is Color) { var color = (Color) value; var intCode = color.ToIntCode(); if (!ColorCache.ContainsKey(intCode)) { ColorCache.Add(intCode, color); } else { if (DuplicateColorNameCache.ContainsKey(intCode)) { var values = DuplicateColorNameCache[intCode].ToList(); values.Add(color.Name); DuplicateColorNameCache[intCode] = values.ToArray(); } else { string[] values = { ColorCache[intCode].Name, color.Name }; DuplicateColorNameCache[intCode] = values; } } } } } /// <summary> /// 返回用十進位格式的顏色值,該值範圍在0~16777215。 /// <para>例:0表示黑色,16777215表示白色。</para> /// </summary> /// <param name="color">Color對象</param> /// <returns>十進位格式的顏色值</returns> public static int ToIntCode(this Color color) { int c = color.R; c = c | color.G << 8; c = c | color.B << 16; return c; //以下代碼等效 //先轉成16進位值,再轉成10進位值 //var hexCode = color.ToHexCode(false);//獲取十六進位格式的顏色代碼值 //int intCode = Convert.ToInt32(hexCode, 16);//獲取十進位格式的顏色代碼值 } /// <summary> /// 返回十六進位格式的顏色值。 /// <para>例:Color.Gray(灰色)返回#808080。Color.FromArgb(192,192,192) 返回#C0C0C0</para> /// </summary> /// <param name="color">Color對象</param> /// <param name="isAddPrefix">是否添加首碼"#", 預設為 true。</param> /// <returns>十六進位格式的顏色值</returns> public static string ToHexCode(this Color color, bool isAddPrefix = true) { return string.Format("{0}{1:X2}{2:X2}{3:X2}", isAddPrefix ? "#" : string.Empty, color.R, color.G, color.B); //下麵這個方法,遇到.NET預定義的顏色對象,會返回顏色名稱,而不是十六進位值。 //return ColorTranslator.ToHtml(color); } /// <summary> /// 返回HTML支持的顏色代碼值,如果顏色已在HTML預定義,則返回顏色名稱,否則返回十六進位格式表示的代碼值。 /// <para>例:Color.Gray(灰色)返回Gray。Color.FromArgb(192,192,192) 返回#C0C0C0(銀白色)</para> /// <para>例:這是因為HTML中已預定義該顏色代碼值,所以HTML支持該顏色代碼值所對應的名稱值。</para> /// <para>.NET有三對預定義顏色的代碼值是相同的,所以當傳入以ARGB表示的顏色對象剛好在這三對預定義顏色範圍,那麼只會返回一對中的其中一個顏色名稱。</para> /// <para>當你需要知道另外一個顏色名稱,你可以通過</para> /// </summary> /// <param name="color">Color對象</param> /// <returns>如果顏色已在HTML預定義,則返回顏色的友好名稱,否則返回十六進位格式表示的代碼值</returns> public static string ToHtmlCode(this Color color) { int intCode = color.ToIntCode(); if (ColorCache.ContainsKey(intCode)) { return ColorTranslator.ToHtml(ColorCache[intCode]); } /* * 上面之所以要這樣做,是因為當使用者傳過來一個使用ARGB表示的Color對象。 * 經過以上處理後,下麵可以順利返回顏色的名稱。 * 例: Color color1 = Color.Gray; //灰色 * Color color2 = Color.FromArgb(color1.A, color1.R, color1.G, color1.B); * color1.ToHtmlCode() 返回"Gray" * color2.ToHtmlCode() 返回"#808080". * 其實以上兩個Color對象是相等的,這兩個對象調用ToHtmlCode()擴展方法都應該返回同一個結果才是比較合理的。 */ return ColorTranslator.ToHtml(color); } /// <summary> /// 獲取具有相同代碼值的顏色名稱數組,如果沒有,則返回null。 /// </summary> /// <param name="color">Color對象</param> /// <returns>返回具有相同代碼值的顏色名稱數組,如果沒有,則返回null。</returns> public static string[] GetDuplicateColorNames(this Color color) { int intCode = color.ToIntCode(); if (DuplicateColorNameCache.ContainsKey(intCode)) { return DuplicateColorNameCache[intCode]; } return null; } /// <summary> /// 轉換十進位格式的顏色代碼值為Color對象 /// </summary> /// <param name="intCode">十進位格式的顏色代碼值</param> /// <returns>返回Color對象</returns> public static Color IntToColor(int intCode) { if (ColorCache.ContainsKey(intCode)) { return ColorCache[intCode]; } /* * 以上處理與ToHtmlCode方法同理 * 先檢查是否與.NET預定義的顏色匹配,如果匹配,返回.NET預定義的顏色對象(該對象包含一個可被直接理解的顏色友好名稱)。 * 如果不匹配,則返回用ARGB表示的Color對象。 */ string hexCode = Convert.ToString(intCode, 16); return ColorTranslator.FromHtml("#" + hexCode); } /// <summary> /// 轉換以"#"開頭的六位長度的十六進位格式的顏色代碼值或.NET預定義的顏色名稱為Color對象 /// </summary> /// <param name="hexCodeOrColorName">.NET預定義的顏色名稱或以"#"開頭的6位長度的十六進位顏色代碼值</param> /// <returns></returns> public static Color HexOrNameToColor(string hexCodeOrColorName) { if (string.IsNullOrEmpty(hexCodeOrColorName)) { return Color.Empty; } try { //This is hex code. if (hexCodeOrColorName[0] == '#') { string hexCode = hexCodeOrColorName.Substring(1); int intCode = Convert.ToInt32(hexCode, 16); if (ColorCache.ContainsKey(intCode)) { //返回擁有友好名稱的Color對象 return ColorCache[intCode]; } //返回以ARGB表示的Color對象 return ColorTranslator.FromHtml(hexCodeOrColorName); } //This is color name. return ColorTranslator.FromHtml(hexCodeOrColorName); } catch (Exception) { return Color.Empty; } } }