DevPinoy.org
A Filipino Developers Community
            

How To: Create a .NET Color Chart using Reflection

I had a little downtime today so i decided to create something useful(ala coding4fun) and one of the things that i wish i have in my toolbox is an .NET color chart since most of the time i tend to look at what colors i could use when matching my controls with my UI's theme(stylesheets? nah, that only works for the web.. how about if its a windows app? see! 'nuf sed!). Plus, i'd like to play with alittle bit of Reflection today and some basic Generics(hmmm, seems like i'm already dead hooked with this one)

So lets begin coding.

System.Drawing.Color is a pretty cool class, as the class name and namespace would suggest... it deals with colors for objects. the cool thing about System.Drawing.Color contains 141 named colors which is useful if you don't know how to use the #RRGGBB format(which most people really don't). The only crappy thing about this class is that it doesnt have a GetEnumerator method inside its definition which makes it alittle bit more tricky to iterate on all those beautiful(my exageration) 141 colors. This is where Reflection comes into play. Reflection in laymans term is defined as the ability to get detailed information about classes, fields, methods, properties, and other code elements at runtime.. it's like, going to the movie(assembly) and knowing that it sucks while watching it(reflection).

System.Reflection is the namespace where you can get classes and methods that you can use for "reflecting" assemblies. You can read more about Reflection here.

Ok now, so i know that i want to read the class System.Drawing.Color and get the Color instances inside of it.. so.. what should i do?

Knowing that Reflection has the ability to read assemblies makes this problem eassy to solve. The first thing that we need is to create a class that would get all the colors contained in the System.Drawing.Color class. Here's what we need to do: read the class information by specifying a known color from the Color class, get its type, get the properties contained in that class by specifying what binding attribute we want to use, create a PropertyInfo[] to hold our accumulated properties, iterate thru the PropertyInformation[] and add it to a generic list. Whew.. sounds easy huh?

Here' the code listing for our ColorCollection class based on how i described it from above:

using System;
using System.Drawing;
using System.Reflection;
using System.Collections.Generic;

/// <summary>
/// Summary description for ColorCollection
/// </summary>
public class ColorCollection: List<Color>
{
   public List<Color> Colors
   {
      get { return GetColors(); }
   }

   private List<Color> GetColors()
   {
      //create a generic list of Color
      List<Color> colors = new List<Color>();

      //get an array of PropertyInfo using the our known color and specifying the proper binding flags
      PropertyInfo[] propertyInfoList = Color.Red.GetType().GetProperties(
                                                         BindingFlags.Static | 
                                                         BindingFlags.DeclaredOnly | 
                                                         BindingFlags.Public);

      //iterate thru the assembly properties
      for (int propertyIndex = 0; propertyIndex < propertyInfoList.Length; propertyIndex++)
      {
         //retrieve the property info
         PropertyInfo propertyInfo = (PropertyInfo)propertyInfoList[propertyIndex];
         //add the color to our list
         colors.Add((Color)propertyInfo.GetValue(null, null));
      }

      //return the color list
      return colors;
   }
}

Now lets use this class to build our ASP.NET page that would display our color. What i did was add a DataList in an ASP.NET page and format the Datalist's ItemTemplate by adding a Panel control(to show the color by modifying its BackColor property on DataBind) and a Label control(to display the color name). Below is a code listing of how i formatted my DataList:

<asp:DataList ID="colorList" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
 <ItemTemplate>
  <asp:Panel ID="colorPanel" runat="server" Height="100px" HorizontalAlign="Center"
                    Width="100px" BackColor='<%# Color.FromName(Eval("Name").ToString()) %>' BorderStyle="Solid" BorderWidth="1px">
        </asp:Panel>
        <asp:Label ID="lblColor" runat="server" Font-Size="Small" Text='<%# Eval("Name") %>' Font-Bold="True" Font-Names="Arial"></asp:Label>
                <br />
                <br />
 </ItemTemplate>
    <SeparatorTemplate>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 </SeparatorTemplate>
</asp:DataList>

The next step is binding our ColorCollection class to our Datalist which is pretty easy:

protected void Page_Load(object sender, EventArgs e)
{
   ColorCollection cc = new ColorCollection();
   colorList.DataSource = cc.Colors;
   colorList.DataBind();
}

Below is a screenshot of our ASP.NET page:


You can download the final project here: KeithRull.GDIColorChart.zip (2.98 KB)

Final Thoughts: hmmm... none. I think playing with ASP.NET kills your boredom big time :P Happy Coding!


Posted Sep 25 2006, 12:38 PM by keithrull

Comments

cvega wrote re: How To: Create a .NET Color Chart using Reflection
on 09-25-2006 6:59 PM

Instead of reflecting static values to get the names of known colors, there is an Enum called KnownColors in System.Drawing namespace that has all the names of "known" colors in .NET, including SystemColors. You can separate SystemColors from the names by comparing it to KnownColors.Transparent or value 27, because SystemColors are enumerated first. Here's a small code I used before to populate a comboBox named "cboColors" with color names and color hex (ARGB):

comboBox1.Items.Clear();

string[] colorNames = Enum.GetNames(typeof(KnownColor));

// 27 = Transparent (Any value below are SystemColors)

foreach(string colorName in colorNames)

{

KnownColor kcolor = (KnownColor)Enum.Parse(typeof(KnownColor),

                                                                                   colorName);

if (kcolor >= KnownColor.Transparent)

{

cboColors.Items.Add(colorName + " = " +

Color.FromKnownColor(kcolor)

                                               .ToArgb().ToString("x8"));

}

}

Cheers,

-chris

cvega wrote re: How To: Create a .NET Color Chart using Reflection
on 09-25-2006 7:14 PM

Oops, ignore "comboBox1.Items.Clear();" line.

Cheers,

-chris

keithrull wrote re: How To: Create a .NET Color Chart using Reflection
on 09-26-2006 1:37 PM

hehehe. i was really bored yesterday and just found a good excuse to use reflection.

i think your approach is pretty neat. thanks chris!

Keith Rull wrote How To: Creating a .NET Color Chart revisited
on 09-26-2006 5:28 PM

After reviewing my first example .. i realized that doing reflection is not the easy way to do get the

Driving .NET wrote XAML renders differently
on 10-03-2006 1:25 PM

I was reading with great interest Keith's posts about creating a color chart in ASP.NET and decided to

Driving .NET wrote XAML renders differently
on 11-11-2006 10:28 AM

I was reading with great interest Keith's posts about creating a color chart in ASP.NET and decided to

SatishKumar wrote re: How To: Create a .NET Color Chart using Reflection
on 12-03-2006 9:06 PM

when i use the above code for displaying color chart, I am not getting any output as shown above. Its giving an error like "The name 'color' does not exist in the current context". what i have to do for that ?

Regards

Satishkumar

Ken wrote re: How To: Create a .NET Color Chart using Reflection
on 06-30-2007 9:56 PM

How About this code for populating a combo box the point is to USE the greater than 26 to get in order to ADD the web colors - as > = 27 requires two tests. is it > or = where as > means only one operation - for this item NO BIG DEAL - but in the long run every step saved speeds up the app. remember 1000 iterations saves 1000 steps..

 For Each iValue As Int32 In System.Enum.GetValues(GetType(System.Drawing.KnownColor))

           If iValue > 26 Then

               Website_cmbBackColor.Items.Add([Enum].GetName(GetType(System.Drawing.KnownColor), iValue))

           End If

       Next

john o. wrote re: How To: Create a .NET Color Chart using Reflection
on 01-01-2008 3:26 PM

Silverlight doesn't support System.Drawing...but it does support reflection. Heres a LINQ version...

       Color[] GetEnumeratedColors()

       {

           return typeof(Colors).GetProperties() .Select(color => (Color)color.GetValue(typeof(Colors), null)).ToArray<Color>();

       }

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:

Copyright DevPinoy 2005-2008
Powered by Community Server (Commercial Edition), by Telligent Systems