/// <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 << ;
c = c | color.B << ; 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, );
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[] == '#')
{
string hexCode = hexCodeOrColorName.Substring();
int intCode = Convert.ToInt32(hexCode, );
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;
}
}
}

颜色扩展类--ColorExtensions的更多相关文章

  1. C# 扩展类

    C# 中提供一个非常实用的供能,扩展方法(Extension method) 扩展方法是通过额外的静态方法扩展现有的类型.通过扩展方法,可以对已有类型做自己想做的相关扩展.方法:定义静态类,扩展方法也 ...

  2. tp中调用PHP系统扩展类

    例如使用Redis扩展类: use Reids; $redis = new Redis();

  3. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

  4. Thinkphp编辑器扩展类kindeditor用法

    一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的Th ...

  5. 扩展javascript扩展(类,对象,原型)

     扩展javascript扩展(类,对象,原型)

  6. PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载

    文章转载自:https://my.oschina.net/junn/blog/104464 PHP ZipArchive 是PHP自带的扩展类,可以轻松实现ZIP文件的压缩和解压,使用前首先要确保PH ...

  7. ASP.NET MVC4 HtmlHelper扩展类,实现分页功能 @Html.ShowPageNavigate

    本文主要做了一个HtmHelper类的分页扩展函数,方便在视图中调用,有需要的朋友可以参考一下,希望对大家有所帮助. 1.扩展HtmlHelper类方法ShowPageNavigate output. ...

  8. C#操作Xml树的扩展类

    本文提供一个操作Xml树的扩展类,与将xml字符串直接映射成实体对象的使用方法,供大家参考,学习. 下面附上源码 using System; using System.Collections.Gene ...

  9. 基于Thinkphp3.2的qq第三方oauth认证登录扩展类

    基于Thinkphp3.2的qq第三方oauth认证登录扩展类,由于腾讯oauth sdk写的太多,不能与thinkphp和好的结合,最终想法讲腾讯oauth sdk写成tp的扩展类先看代码,将代码保 ...

随机推荐

  1. LeetCode 51 N-Queens II

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  2. 3里氏代换原则LSP

    一.什么是里氏代换原则 里氏代换原则(Liskov Substitution Principle): 一个软件实体如果使用的是一个父类的话,那 么一定适用于其子类,而且它察觉不出父类和子 类对象的区别 ...

  3. Spring Security http标签的use-expressions="true"属性

    如果声明为true,那么在access属性要用hasRole()这样写: <intercept-url pattern="/secure/extreme/**" access ...

  4. 在微信下载app引导页代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Dev_GridView:设置列为Button

    1. gridview ——run designer ——columns ——columns Edit选择repositoryItemButtonEdit1列 2. 更改colums ——showBu ...

  6. 窗口,父窗口parentwindow,所有者窗口ownerwindow

    参考文档:http://www.cnblogs.com/fwycmengsoft/p/4026592.html 一. parent:创建者,owner:所有者 小玉的父母生下小玉,养到8岁,卖给贾府当 ...

  7. 如何使用onclick方式添加多个事件回调函数

    通过给onclcik包裹一个函数进行上下文的切换与参数的传递: function addClcikEvent(el, fn){ if(el.onclick){ var _back = el.oncli ...

  8. Java编程基础篇第二章

    关键字 概述:被Java语言赋予特定含义的单词. 特点:组成关键字的字母全部为小写字母. 标识符 概述:给类,接口,包,方法,常量起名字时的字符序列 组成规则:英文大小写字母,数字,$和— 命名规则. ...

  9. 【Linux内存源码分析】vmalloc不连续内存管理(转)

    https://www.jeanleo.com/2018/09/09/%E3%80%90linux%E5%86%85%E5%AD%98%E6%BA%90%E7%A0%81%E5%88%86%E6%9E ...

  10. bug修复记录

    telnet 网址 ping netaddr traceroute netaddr ,这是一个linux下的命令可以通过Vmmap观察程序运行时所需要的依赖库协议里面涉及到数组的, 一定要判断最大值 ...