One of the things we take for granted in the Web world is the ability to define colors using hex notation. For example, #000000 is black, #FFFFFF is white, and so on.
Unfortunately Silverlight doesn’t have a built-in way to create a System.Windows.Media.Color structure using hex notation. Wouldn’t it be nice if we could write code like this?
// Create a color from its hex code
HexColor color = new HexColor("#FF0000");
// And use it anywhere we'd use a normal Color
// structure without having to cast anything
Brush brush = new SolidColorBrush(color);
Well, it turns out we can. Here’s a little class I created to do the job:
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Media;
public struct HexColor
{
// Regex: This pattern matches hex codes in these two formats:
// #000000 (no alpha value) and #FF000000 (alpha value at front).
const string HEX_PATTERN = @"^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{8})$";
const int LENGTH_WITH_ALPHA = 8;
Color _color;
public HexColor(string hexCode)
{
if (hexCode == null)
{
throw new ArgumentNullException("hexCode");
}
if (!Regex.IsMatch(hexCode, HEX_PATTERN))
{
throw new ArgumentException(
"Format must be #000000 or #FF000000 (no extra whitespace)",
"hexCode");
}
// shave off '#' symbol
hexCode = hexCode.TrimStart('#');
// if no alpha value specified, assume no transparency (0xFF)
if (hexCode.Length != LENGTH_WITH_ALPHA)
hexCode = String.Format("FF{0}", hexCode);
_color = new Color();
_color.A = byte.Parse(hexCode.Substring(0, 2), NumberStyles.AllowHexSpecifier);
_color.R = byte.Parse(hexCode.Substring(2, 2), NumberStyles.AllowHexSpecifier);
_color.G = byte.Parse(hexCode.Substring(4, 2), NumberStyles.AllowHexSpecifier);
_color.B = byte.Parse(hexCode.Substring(6, 2), NumberStyles.AllowHexSpecifier);
}
public byte A
{
get { return _color.A; }
set { _color.A = value; }
}
public byte R
{
get { return _color.R; }
set { _color.R = value; }
}
public byte G
{
get { return _color.G; }
set { _color.G = value; }
}
public byte B
{
get { return _color.B; }
set { _color.B = value; }
}
// Implicit cast from HexColor to Color
public static implicit operator Color(HexColor hexColor)
{
return hexColor._color;
}
// Implicit cast from Color to HexColor
public static implicit operator HexColor(Color color)
{
HexColor c = new HexColor();
c._color = color;
return c;
}
// Just like with Color, ToString() prints out the hex value of the
// color in #ARGB format (example: #FF000000) by default.
public override string ToString()
{
return ToString(true);
}
// I don't always need the alpha value, so I added an overload here
// that lets me return the hex value in #RBG format (example: #000000).
public string ToString(bool includeAlpha)
{
if (includeAlpha)
{
return _color.ToString();
}
else
{
return String.Format("#{0}{1}{2}",
_color.R.ToString("x2"),
_color.G.ToString("x2"),
_color.B.ToString("x2"));
}
}
}
That’s it. Now I can seamlessly work with Colors and hex values interchangeably, and my life as a Silverlight developer has gotten a little bit easier.