DevPinoy.org
A Filipino Developers Community
            

How To: Creating a .NET Color Chart revisited

After reviewing my first example.. i realized that doing reflection is not the easy way to do get the known color collection(thanks to Chris Vega who pointed to me the Enum called KnownColor which basically contains .NET known colors). Somebody also told me that the demo would be nicer if the colors are real images instead of just painting a panel(which makes really sense if you are thinking of saving the generated image in your desktop). With this suggestions i decided to create a revised version of our Color Chart Generator.

3 things to note about this new version:
1.) We are not using reflection anymore, instead we are parsing the enum to a string array and adding those values(only non-system colors) to List<strings>.
2.) We are now using <%# Container.DataItem %> in the DataList ItemTemplates since the values that we are now binding is an array of strings.
3.) We are now generating images on the fly instead of just changing the color of a panel object.

Here's the modified ColorCollection class
using System;
using System.Drawing;
using System.Reflection;
using System.Collections.Generic;

/// <summary>
/// Summary description for ColorCollection
/// </summary>
public class ColorCollection
{
   public List<string> Colors
   {
      //return the color name list
      get { return GetColors(); }
   }

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

      //get the color names from the Known color enum
      string[] colorNames = Enum.GetNames(typeof(KnownColor)); ;

      //iterate thru each string in the colorNames array
      foreach (string colorName in colorNames)
      {
         //cast the colorName into a KnownColor
         KnownColor knownColor = (KnownColor)Enum.Parse(typeof(KnownColor), colorName);

         //check if the knownColor variable is a System color
         if (knownColor > KnownColor.Transparent)
         {
            //add it to our list
            colors.Add(colorName);
         }
      }

      //return the color list
      return colors;
   }
}

As you can see, the color names are now coming from the KnownColor enum which we are able to get by using the Enum.GetNames function. We then iterate thru all the strings in our string array(colorNames) and convert those names into a KnownColor value. The final step for our ColorCollection class is to determine if the color is greater than KnownColor.Transparent(27) because we are only concerned about non-system colors.

The next step is to create our Generic Handler which we will use to generate our custom image on the fly. Below is the code for our Generic Handler:

<%@ WebHandler Language="C#" Class="ImageBoxHandler" %>

using System;
using System.Web;
using System.Drawing;

public class ImageBoxHandler : IHttpHandler {

   Size size = new Size(100, 100);

   public void ProcessRequest (HttpContext context) {

      //check if the current request has backcolor as part of its query string parameter
      if (context.Request.QueryString["backcolor"] != null)
      {
         //get the query string value
         string backColor = context.Request.QueryString["backcolor"].ToString();
         //set our response.content type to image/jpeg
         context.Response.ContentType = "image/jpeg";
         //create a new Bitmap object with the height and width set to 100
         using (Bitmap bitmap = new Bitmap(size.Width,size.Height))
         {
            //create a new Rectangle with a 0,0 coordinates and with the height and width set to 100
            Rectangle rectangle = new Rectangle(0, 0, size.Width, size.Height);
            {
               //create our graphics object from our Bitmap object
               using (Graphics graphics = Graphics.FromImage(bitmap))
               {
                  //create our brush
                  using (SolidBrush brush = new SolidBrush(Color.FromName(backColor)))
                  {
                     //fill the rectangle with the color specified from above
                     graphics.FillRectangle(brush, rectangle);
                  }
               }
               //save the bitmap to our response stream
               bitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
         }
      }
   }

   public bool IsReusable {
      get {
         return false;
      }
   }
}

ProcessRequest as the name would imply is a method of the IHttpHandler interface that enables you to process an HTTP request of a custom HttpHandler that implements the IHttpHandler interface.

The first thing that we did inside this function is to check if the required query string named backcolor exist in the current request. We then get its value and assign it to a variable called backColor. We also modified the response.contenttype telling the browser that the Httphandler would be returning an image as it's response. Next, we created a Bitmap object that we have set to 100x100 which we will be using to house our Rectangle. The Rectangle object will serve as our 'painting' panel. A Graphics object would then be used read our bitmap object. A Brush is an object that i used to 'paint' graphic objects. In our case, we would be using a SolidBrush and specifying the paint color our backColor variable to paint our Rectangle. The last step is to save the bitmap to the outputstream.

Setting up our DataList:
<asp:DataList ID="colorList" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
 <ItemTemplate>
  <asp:Image id="Image1" runat="server" ImageUrl='<%# String.Format("ImageBoxHandler.ashx?backcolor={0}", Container.DataItem) %>'></asp:Image>
  <br />
        <asp:Label ID="lblColor" runat="server" Font-Size="Small" Text='<%# Container.DataItem %>' Font-Bold="True" Font-Names="Arial"></asp:Label>
        <br />
  <br />
    </ItemTemplate>
 <SeparatorTemplate>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 </SeparatorTemplate>
</asp:DataList>

As you can see from the code listing above, we have modified the ImageUrl property of the Image control to point to our HttpHandler. We also changed the way we pass values on DataBind because we only have an array strings being pass to our DataList.

The Page_Load event contents is still the same as the previous article since there isn't really anything that changed on the way that we bind the data.

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

So what have we learned?
You can convert an Enum to a string[].
You can convert a value to an Enum value.
You can create HttpHandlers to serve custom images on the fly.
You can bind string[] to a control by just using Container.DataItem.

Download the source here: KeithRull.GDIColorChartV2.zip (3.74 KB)

Final thoughts: People can teach you new things! So always listen and be attentive because you'll never know when the next burst of knowledge would come out.


Posted Sep 26 2006, 05:26 PM by keithrull

Comments

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

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

kierepka wrote re: How To: Creating a .NET Color Chart revisited
on 10-09-2006 3:46 AM

Nice but not working on Compact Framework (there sie no KnowColors in CF... ;()

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

shachi wrote re: How To: Creating a .NET Color Chart revisited
on 01-18-2007 9:31 PM

its great!

punk22 wrote re: How To: Creating a .NET Color Chart revisited
on 06-05-2008 10:55 PM

hey Keith that's great.I can give you a better option to Make your chart look even more than this chk this out "visifire"

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