| File: System\Drawing\ColorConverter.cs | Web Access |
| Project: src\runtime\src\libraries\System.ComponentModel.TypeConverter\src\System.ComponentModel.TypeConverter.csproj (System.ComponentModel.TypeConverter) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; namespace System.Drawing { public class ColorConverter : TypeConverter { private static readonly Lazy<StandardValuesCollection> s_valuesLazy = new Lazy<StandardValuesCollection>(() => { // We must take the value from each hashtable and combine them. var set = new HashSet<Color>(ColorTable.Colors.Values); return new StandardValuesCollection(set.OrderBy(c => c, new ColorComparer()).ToList()); }); public ColorConverter() { } public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(true)] Type? destinationType) { return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType); } public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is string strValue) { return ColorConverterCommon.ConvertFromString(strValue, culture ?? CultureInfo.CurrentCulture); } return base.ConvertFrom(context, culture, value); } public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { ArgumentNullException.ThrowIfNull(destinationType); if (value is Color c) { if (destinationType == typeof(string)) { if (c == Color.Empty) { return string.Empty; } // If this is a known color, then Color can provide its own name. // Otherwise, we fabricate an ARGB value for it. if (ColorTable.IsKnownNamedColor(c.Name)) { return c.Name; } else if (c.IsNamedColor) { return "'" + c.Name + "'"; } culture ??= CultureInfo.CurrentCulture; string sep = culture.TextInfo.ListSeparator + " "; TypeConverter intConverter = TypeDescriptor.GetConverterTrimUnsafe(typeof(int)); string?[] args; int nArg = 0; if (c.A < 255) { args = new string?[4]; args[nArg++] = intConverter.ConvertToString(context, culture, (object)c.A); } else { args = new string[3]; } // Note: ConvertToString will raise exception if value cannot be converted. args[nArg++] = intConverter.ConvertToString(context, culture, (object)c.R); args[nArg++] = intConverter.ConvertToString(context, culture, (object)c.G); args[nArg++] = intConverter.ConvertToString(context, culture, (object)c.B); return string.Join(sep, args); } else if (destinationType == typeof(InstanceDescriptor)) { MemberInfo? member; object[]? args = null; if (c.IsEmpty) { member = typeof(Color).GetField("Empty"); } else if (ColorTable.IsKnownNamedColor(c.Name)) { member = typeof(Color).GetProperty(c.Name) ?? typeof(SystemColors).GetProperty(c.Name); } else if (c.A != 255) { member = typeof(Color).GetMethod("FromArgb", new Type[] { typeof(int), typeof(int), typeof(int), typeof(int) }); args = new object[] { c.A, c.R, c.G, c.B }; } else if (c.IsNamedColor) { member = typeof(Color).GetMethod("FromName", new Type[] { typeof(string) }); args = new object[] { c.Name }; } else { member = typeof(Color).GetMethod("FromArgb", new Type[] { typeof(int), typeof(int), typeof(int) }); args = new object[] { c.R, c.G, c.B }; } Debug.Assert(member != null, "Could not convert color to member. Did someone change method name / signature and not update ColorConverter?"); if (member != null) { return new InstanceDescriptor(member, args); } else { return null; } } } return base.ConvertTo(context, culture, value, destinationType); } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context) { return s_valuesLazy.Value; } public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true; private sealed class ColorComparer : IComparer<Color> { public int Compare(Color left, Color right) => string.CompareOrdinal(left.Name, right.Name); } } }