Skip to content


Adding new looks / functionality to exsiting .NET controls - ListBox.

So I am starting a series of posts that involves extending the default .NET controls to add new looks as well as new functionality. Today we will be extending the ListBox, so let’s get started.

The new listbox that we will create will have a main text or title and a description text below it as well as the ability to add an image on the control.

To get started we will create a class which I will name ListBoxItem which will contain the new properties that will be added to the control (Title, description, image).

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Drawing;
  5.  
  6. namespace ListBoxEx
  7. {
  8.     public class ListBoxItem
  9.     {
  10.         Image image;
  11.         string text;
  12.         string desc;
  13.  
  14.         public Image Image
  15.         {
  16.             get
  17.             {
  18.                 return image;
  19.             }
  20.             set
  21.             {
  22.                 image = value;
  23.             }
  24.         }
  25.  
  26.         public string Text
  27.         {
  28.             get
  29.             {
  30.                 return text;
  31.             }
  32.             set
  33.             {
  34.                 text = value;
  35.             }
  36.         }
  37.  
  38.  
  39.         public string Desc
  40.         {
  41.             get
  42.             {
  43.                 return desc;
  44.             }
  45.             set
  46.             {
  47.                 desc = value;
  48.             }
  49.         }
  50.     }
  51. }

So now that we got that done we can get started with the ListBox itself. We are going to create a class to extend the original ListBox control.

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Drawing;
  5. using System.Drawing.Drawing2D;
  6. using System.Windows.Forms;
  7.  
  8. namespace ListBoxEx
  9. {
  10.     public class ListBoxEx : ListBox
  11.     {
  12.        
  13.     }
  14. }

Now lets start with the ListBoxEx class. Firstly we will add a constructor to the class and we will set the ItemHeight in it. We could set the ItemHeight dynamically by using the combined height of the strings or the height of the image.

  1. public ListBoxEx()
  2. {
  3.     this.ItemHeight = 35;
  4. }

Now lets write the method that sets up the drawing of the items.
What we will do here is firstly check that we have a valid index if so then select the currently active item. After that we are going to check if it is selected or not then draw either a gradient background or the standard background. Then draw the image if one is used then the text.

  1. protected override void OnDrawItem(DrawItemEventArgs e)
  2. {
  3.     //Lets grab are current item from the list of items, as well as check to see
  4.     //that we actually have a valid index for are item.
  5.  
  6.     if (this.Items.Count > 0)
  7.     {
  8.         ListBoxItem item = (ListBoxItem)this.Items[e.Index];
  9.         Color textColor = this.ForeColor;
  10.         bool isUsingImage = false;
  11.         int textMargin = 2;
  12.  
  13.         //Check to see that we actually have an image.
  14.         if (item.Image != null)
  15.             isUsingImage = true;
  16.  
  17.         e.DrawFocusRectangle();
  18.  
  19.         //Draw are graident background if the control is selected otherwise the standard background.
  20.         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
  21.         {
  22.             e.Graphics.FillRectangle(new LinearGradientBrush(new Point(0, 0), new Point(0, this.ItemHeight),
  23.                 Color.LightSkyBlue, Color.LightSteelBlue), e.Bounds);
  24.             textColor = Color.White;
  25.         }
  26.         else
  27.         {
  28.             e.Graphics.FillRectangle(new SolidBrush(SystemColors.Window), e.Bounds);
  29.         }
  30.  
  31.         //Draw are image if one is being used then draw the text.
  32.         if (isUsingImage)
  33.         {
  34.             Rectangle imgRect = new Rectangle();
  35.             imgRect.Location = new Point(2, (e.Bounds.Y + 2));
  36.             imgRect.Size = new Size(20, 20);
  37.  
  38.             e.Graphics.DrawImage(item.Image, imgRect);
  39.             textMargin = 26;
  40.         }
  41.  
  42.         //We can extend this even further by using the TextRender class and be able to add an ellipsis to are strings if they go beyond the
  43.         //edge of the control and all sorts of other nifty things.
  44.         e.Graphics.DrawString(item.Text, new Font(this.Font.FontFamily, 10, FontStyle.Regular),
  45.             new SolidBrush(textColor), new PointF(textMargin, (e.Bounds.Y + 2)));
  46.         e.Graphics.DrawString(item.Desc, this.Font, new SolidBrush(textColor), new PointF(textMargin, (e.Bounds.Y + 20)));
  47.     }
  48.  
  49.     base.OnDrawItem(e);
  50. }

Here is the result of what I got as well as the download of the project and code.

ListBoxEx Screenshot

ListBoxEx Screenshot

ExtendedControls - ListBoxEx (55)

Posted in .NET, C#, Software, code..

0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.