The Daily WPF
Custom Markup Extensions in WPF 
Thursday, September 25, 2008, 01:45 PM
Posted by Ruben Steins
A nice post by raasiel on dZone about writing a simple Custom MarkupExtension.



He creates a MarkupExtension you can use to automatically create a lighter and darker shade of a color for MouseOver effects. Interesting, although he doesn't post the code to actually create a darker or lighter color.
After reading A good introduction to the different color models that exist, I decided that the easiest a way to achieve the lighter and darker colors would be to use the HSL colormodel and adjust the lightness. The selected color would have a L of 50%, the darker would have a bit less, the lighter a bit more.
Now, since WPF uses RGB by default, we have to do some conversion. These code samples give a conversion algorithm, , and converting them to C# isn't really hard:


ColorHSL RGBtoHSL(Color colorRGB)
{
ColorHSL hsl = new ColorHSL();

float r, g, b, h, s, l; //this function works with floats between 0 and 1
r = colorRGB.R / 256.0f;
g = colorRGB.G / 256.0f;
b = colorRGB.B / 256.0f;

float maxColor = Math.Max(r, Math.Max(g, b));
float minColor = Math.Min(r, Math.Min(g, b));


//R == G == B, so it's a shade of gray
if ( r == g && r == b )
{
h = 0.0f; //it doesn't matter what value it has
s = 0.0f;
l = r; //doesn't matter if you pick r, g, or b
}
else
{
l = (minColor + maxColor) / 2;

if (l < 0.5) s = (maxColor - minColor) / (maxColor + minColor);
else s = (maxColor - minColor) / (2.0f - maxColor - minColor);

if(r == maxColor) h = (g - b) / (maxColor - minColor);
else if(g == maxColor) h = 2.0f + (b - r) / (maxColor - minColor);
else h = 4.0f + (r - g) / (maxColor - minColor);

h /= 6; //to bring it to a number between 0 and 1
if(h < 0) h ++;
}

hsl.H = (short)(h * 255);
hsl.L = (short)(l * 255);
hsl.S = (short)(s * 255);

return hsl;
}


So, if we have the color as HSL, we can simply change the lightness and get the light and dark variant:


ColorHSL lightColor = (short)(normalColor.H * 1.5);
ColorHSL darkColor = (short)(darkColor.H * 0.5);


After this we have to convert back to RGB (mind you, this code is needs some improvements):

Color HSLtoRGB(ColorHSL colorHSL)
{
double r, g, b, h, s, l; //this function works with floats between 0 and 1
double temp1, temp2, tempr, tempg, tempb;
h = colorHSL.H / 256.0;
s = colorHSL.S / 256.0;
l = colorHSL.L / 256.0;

//If saturation is 0, the color is a shade of gray
if (s == 0)
{
r = g = b = l;
}
else
{
//Set the temporary values
if (l < 0.5)
{
temp2 = l * (1 + s);
}
else
{
temp2 = (l + s) - (l * s);
}

temp1 = 2 * l - temp2;
tempr = h + 1.0 / 3.0;

if (tempr > 1)
{
tempr--;
}

tempg = h;
tempb = h - 1.0 / 3.0;
if (tempb < 0)
tempb++;

//Red
if (tempr < 1.0 / 6.0) r = temp1 + (temp2 - temp1) * 6.0 * tempr;
else if (tempr < 0.5) r = temp2;
else if (tempr < 2.0 / 3.0) r = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempr) * 6.0;
else r = temp1;

//Green
if (tempg < 1.0 / 6.0) g = temp1 + (temp2 - temp1) * 6.0 * tempg;
else if (tempg < 0.5) g = temp2;
else if (tempg < 2.0 / 3.0) g = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempg) * 6.0;
else g = temp1;

//Blue
if (tempb < 1.0 / 6.0) b = temp1 + (temp2 - temp1) * 6.0 * tempb;
else if (tempb < 0.5) b = temp2;
else if (tempb < 2.0 / 3.0) b = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - tempb) * 6.0;
else b = temp1;
}

return Color.FromRgb(Convert.ToByte(r*255), Convert.ToByte(g*255), Convert.ToByte(b*255));
}

If you use this code to calculate the colors you get this:



With this code you can complete your custom Markup Extension.
add comment   |  permalink   |  related link   |   ( 2.9 / 21 )

<<First <Back | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Next> Last>>