Today I stumbled over a thread in the WPF forum in which the OP was looking for a way to retrieve the (known) name for a given color.
That is, given a color such as #FFB22222 (or ARGB :: 255, 178, 32, 32), to retrieve "Firebrick". What I thought was darn simple actually isn't, because System.Windows.Media.Colors is a class and thus exposes all (known) colors as properties (as opposed to System.Drawing.KnownColor which is an enum). So there really isn't any other way than to use reflection to obtain a list of all colors. Here's a little helper class that returns the name of a color passed to it:
Retrieving the name of a given Color object
/// <summary>
/// Returns the known name of the color passed (if found), or an empty string.
/// </summary>
/// <param name="clr">The color whose name is to be returned.</param>
/// <returns>
/// The name of the passed color resp. an empty string if
/// no matching known color could be found.
/// </returns>
public static string GetKnownColorName(Color clr)
{
Color clrKnownColor;
//Use reflection to get all known colors
Type ColorType = typeof(System.Windows.Media.Colors);
PropertyInfo[] arrPiColors = ColorType.GetProperties(BindingFlags.Public | BindingFlags.Static);
//Iterate over all known colors, convert each to a <Color> and then compare
//that color to the passed color.
foreach (PropertyInfo pi in arrPiColors)
{
clrKnownColor = (Color)pi.GetValue(null, null);
if (clrKnownColor == clr) return pi.Name;
}
return string.Empty;
}
If you call the above method with i.e. ...
string strColorName = GetKnownColorName(Color.FromArgb(255, 178, 32, 32));
MessageBox.Show(strColorName == "" ? "(None found)" : strColorName);
... the MessageBox will show "Firebrick".
Update to the above (Feb 13 2010)
I just updated the code for the method above after it became obvious that the GetHashCode() method is not returning unique values. I did a bit of searching in order to find out more about that, but couldn't find anything; the docs are no help at all with this respect or even when it comes to the reason for the existance of this method in the first place.
Actually, I don't have the slightest idea as to how the hashes couldn't be unique - colors resp. their ARGB values are uniqe in itself after all. However, the hashes for Colors.White and Colors.Blue are equal. Now if that isn't plain stupid! Lesson learned: never assume anything ...
Thanks to Pedro for catching this (see the comments).
Retrieving a list with all known colors (names + Color objects)
If you actually need a list with all color values and their name-counterparts (might make sense if you need this frequently), here's another little helper-method that will return all known colors along with the name of each color:
/// <summary>
/// Returns a list containing all known colors, each as a KeyValuePair with the name
/// as the key and the Color as the value.
/// </summary>
public static List<KeyValuePair<string, Color>> GetKnownColors()
{
List<KeyValuePair<string, Color>> lst = new List<KeyValuePair<string, Color>>();
Type ColorType = typeof(System.Windows.Media.Colors);
PropertyInfo[] arrPiColors = ColorType.GetProperties(BindingFlags.Public | BindingFlags.Static);
foreach (PropertyInfo pi in arrPiColors)
lst.Add(new KeyValuePair<string, Color>(pi.Name, (Color)pi.GetValue(null, null)));
return lst;
}
You could use the above in various ways, here's just one sample:
Color clr = Color.FromArgb(255, 178, 32, 32);
List> lstKnownColors = GetKnownColors();
string strColorName = (
from c in lstKnownColors
where
c.Value.A == clr.A &&
c.Value.R == clr.R &&
c.Value.G == clr.G &&
c.Value.B == clr.B
select c.Key
).FirstOrDefault();
Retrieving a color via its name
Last but not least, if you need to go the opposite way, how about another simple helper method:
/// <summary>
/// Returns the Color which is represented by the name passed.
/// </summary>
/// <param name="strColorName">The name of the Color to retrieve.</param>
/// <returns>Nullable color - either the found Color or null.</returns>
public static Color? GetColorByName(string strColorName)
{
Color? clrResult = null;
try
{
object value = ColorConverter.ConvertFromString(strColorName);
if (null != value) clrResult = (Color)value;
}
catch (Exception) { }
return clrResult;
}
Update to the above (Feb 15 2010)
I've just updated the GetColorByName method after Richard pointed out that it was prone to fail if an invalid name or an empty string were passed (see the comments). I've only resolved for a general purpose handler rather than just to catch FormatExceptions.
Wrapping it all up
To simplify things, I dropped the above into a class that you can simply drop into your projects.
Download it here:
C# version: ColorHelpers.cs (3.43 kb)
VB version: ColorHelpers.vb (3.48 kb)
Happy coding!
Location: SinglePost