CameTooFar

A Nerd's False Positive.

How to set Individual Color for ComboBoxItem – C#


Recently, I’s populating some details, say Product Names, into a ComboBox. Yup! populating is simple and direct. After populating I noticed that, the data loaded contains Product Names both New and Obsolete data(means the production has been stopped, long time back) and the only way to differentiate between them is to colorize the products. If that was in Web, we can inject <Style> to achieve the same and it’s straight-forward. But, in Windows Application? There starts the game!

Directly setting the ForeColor of a ComboBoxItem won’t be a solution. If you set the  ForeColor as say, Red. Then, all the ComboBoxItem will have its ForeColor as Red. Then how can you set the ForeColor of Individual ComboBoxItems? Though sounds weird, the solution is tricky.

All you need to do is to handle the DrawItem event of the ComboBox and draw the ComboBoxItem Text (product-name, here) using the DrawString method. DrawItem allows you to control the drawing of a ComboBoxItem. And, DrawString allows you to draw the ComboBoxItem Text in a specified Rectangle, using specified Color (using Brush)and Font.

To simulate the same. I’m binding the ComboBox with List<Products>.

The Products class looks like:

   1:  
   2: public class Products
   3:     {
   4:         /// <summary>
   5:         /// Name of the Product
   6:         /// </summary>
   7:         public string ProductName { get; set; }
   8:  
   9:         /// <summary>
  10:         /// Status of the Product
  11:         /// 1: New/Available Product
  12:         /// 0: Obsolete Product
  13:         /// </summary>
  14:         public short ProductStatus { get; set; }
  15:     }

Now, Bind the ComboBox with List<Products> in the Form_Load().

   1: /// <summary>
   2: /// Bind Product Details with the ComboBox
   3: /// </summary>
   4: private void BindProducts()
   5: {
   6:     // Add Dummy Data
   7:  
   8:     List<Products> listPdt = new List<Products>();
   9:     Products pdt = null;
  10:  
  11:     pdt = new Products();
  12:     pdt.ProductName = "Product 1";
  13:     pdt.ProductStatus = 1;
  14:     listPdt.Add(pdt);
  15:  
  16:     pdt = new Products();
  17:     pdt.ProductName = "Product 2";
  18:     pdt.ProductStatus = 1;
  19:     listPdt.Add(pdt);
  20:  
  21:     pdt = new Products();
  22:     pdt.ProductName = "Product 3";
  23:     pdt.ProductStatus = 1;
  24:     listPdt.Add(pdt);
  25:  
  26:     pdt = new Products();
  27:     pdt.ProductName = "Product 4";
  28:     pdt.ProductStatus = 0;
  29:     listPdt.Add(pdt);
  30:  
  31:     pdt = new Products();
  32:     pdt.ProductName = "Product 5";
  33:     pdt.ProductStatus = 1;
  34:     listPdt.Add(pdt);
  35:  
  36:     // Bind
  37:  
  38:     comboProduct.DataSource = listPdt;
  39:     comboProduct.DisplayMember = "ProductName";
  40:     comboProduct.ValueMember = "ProductStatus";
  41: }

And, the DrawItem Code looks like

   1: private void comboProduct_DrawItem(object sender, DrawItemEventArgs e)
   2: {
   3:     short status = 0;
   4:  
   5:     Brush brush = null;
   6:     ComboBox combo;
   7:  
   8:     try
   9:     {
  10:         e.DrawBackground();
  11:  
  12:         combo = (ComboBox)sender;
  13:         Products pdt = (Products)combo.Items[e.Index];
  14:  
  15:         status = pdt.ProductStatus;
  16:  
  17:         if (status == 0)
  18:         {
  19:             brush = Brushes.Red;
  20:         }
  21:         else
  22:         {
  23:             brush = Brushes.Black;
  24:         }
  25:  
  26:         e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  27:         e.Graphics.DrawString(pdt.ProductName, combo.Font, brush, e.Bounds.X, e.Bounds.Y);
  28:     }
  29:     catch (Exception exp)
  30:     {
  31:         MessageBox.Show(exp.Message);
  32:     }
  33: }
 
A sample screenshot looks like:
 
Combo_Draw_Bg_Selected Combo_Draw_Bg_Selection
 
Have you noticed the blue background selection when the mouse is hovered over the ComboBoxItem and also when the selection is completed. The blue background selection is really annoying, since it takes  away our effort of coloring a ComboBoxItem and clearly a affects readability. And, the next question will be how’ll you remove the annoying blue selection background in the ComboBox?
 
That's bit tricky.
 
The blue selection of ComboBoxItem is actually a  Rectangle with blue background color. All you need to do is to draw the Rectangle through your code; fill it with White color and set it as the background for the ComboBoxItem, using the DrawItem event. Sounds nice, Huh? Here is the code fragment:
 
   1:  
   2: e.Graphics.DrawRectangle(new Pen(Color.White), e.Bounds);
   3: e.Graphics.FillRectangle(Brushes.White, e.Bounds);
 
Hence, the complete code for the DrawItem event looks like
 
   1: private void comboProduct_DrawItem(object sender, DrawItemEventArgs e)
   2: {
   3:     short status = 0;
   4:  
   5:     Brush brush = null;
   6:     ComboBox combo;
   7:  
   8:     try
   9:     {
  10:         e.DrawBackground();
  11:  
  12:         combo = (ComboBox)sender;
  13:         Products pdt = (Products)combo.Items[e.Index];
  14:  
  15:         status = pdt.ProductStatus;
  16:  
  17:         // Determine Status and apply Color
  18:         if (status == 0)
  19:         {
  20:             brush = Brushes.Red;
  21:         }
  22:         else
  23:         {
  24:             brush = Brushes.Black;
  25:         }
  26:  
  27:         // Handle default Blue background selection
  28:         e.Graphics.DrawRectangle(new Pen(Color.White), e.Bounds);
  29:         e.Graphics.FillRectangle(Brushes.White, e.Bounds);
  30:  
  31:         // Draw the Colored String
  32:         e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  33:         e.Graphics.DrawString(pdt.ProductName, combo.Font, brush, e.Bounds.X, e.Bounds.Y);
  34:     }
  35:     catch (Exception exp)
  36:     {
  37:         MessageBox.Show(exp.Message);
  38:     }
  39: }
 
Note:
1. Change the OwnerDraw property of the ComboBox from Normal to DrawModeVariable. Else, the code written in the DrawItem wont have any effect, since the coloring is handled internally.
 
Hope this helps.
Thanks.

IE8 Accelerator Google Define with Preview


Update: This version has been updated to include a scroll bar. You can find more details here.

Internet is a vast resource. Daily, I read a lot of articles from Internet. In between, I always came across difficult terms, either I never heard of or I never remember the exact meaning. As usual, I fire-up another Tab to search for the meaning of that particular term in Google Define service or in any free dictionary service. This is what I usually do.

But searching for a term always in a tab, always break the flow of reading an article. Guess what, search for a word 10+ time drops your interest in reading the article.

Internet Explorer 8 comes with a new feature called Accelerators. In short, Accelerators are keyboard-free, way of browsing Internet.

Will it be nice, if you’re able to look-up for the definition/meaning of a word; without firing another Tab or looping through the free online dictionaries?

That’s what Google Define Accelerator with Preview do for you.

All you’ve to do - Select the text and Select the Accelerator; you got your Definition.

Install

One Click and you can Preview the Definition without leaving the Page.

 
 Preview Enabled
Add To Internet Explorer
 

 

Note: Firefox users can install this addon after installing the FF addon: IE8 Activities (Accelerators) for Firefox.  

 

Preview
ie8_gogdef_prev

 

 Demo
 
 

The First Post

 

What should be the First Post? That was I thinking about.

Being a .NET Developer, I suggest to read this nice and excellent unique work from Joel Spolsky - “The Law of Leaky Abstraction”.

My Big B advised me to know this article, when I’s in Love with .NET.

Here is an excerpt from the article:

TCP attempts to provide a complete abstraction of an underlying unreliable network, but sometimes, the network leaks through the abstraction and you feel the things that the abstraction can't quite protect you from. This is but one example of what I've dubbed the Law of Leaky Abstractions:

All non-trivial abstractions, to some degree, are leaky.

Abstractions fail. Sometimes a little, sometimes a lot. There's leakage. Things go wrong. It happens all over the place when you have abstractions.

I hope everyone will find this worthwhile.

Happy Programming.

Cheers!!!Wink