Click here to Skip to main content
15,886,666 members
Articles / Programming Languages / C#
Article

ListEx - A Sonork like ListBox for .NET

Rate me:
Please Sign up or sign in to vote.
4.80/5 (12 votes)
7 Aug 20027 min read 137K   2.5K   44   11
This is my imitation sonork chat listbox, it supports most of the features of the real thing.

Introduction

This is a little class I whipped up. Its an imitation of the the sonork chat window. Here's a quick list of its features. I describe later in this article exactly how to use each of the features.

  • Draw a coloured line between items
  • Each item can have its own colours for normal and focus state
  • The item can have either a bullet point, or an image of your choice as a bullet [suggested max size is 16x16]
  • Context menu
  • Edit Items
  • The items resize to fit the Icons [image bullet] or text
  • Triggers event for when the Items bullet/icon is clicked.

Disclaimer:  You are free to use this control as you wish, derive from it, add to it, print it out and set it on fire.  Oh, and you can use it both commercially and non-commercially, I don't mind.  But be warned, this code is provided "As Is", if you have a problem, I'll try to help you out, but I will not take responsibility for any  problems caused due to its use.

Note: I will not take responsibility for any fainting, heart attacks or death that may occur through the viewing of my sourcecode.

Using the control

Here's the ingenious part, You use it just as you would any other listbox! Of course, with a few changes. To enable each item to have its own colours, each items is assigned an ItemInfo object, and for this reason, DO NOT add items to the ListEx.Items array, as it will cause problems. For this purpose, I have included two functions, the overloaded Add method, and the Remove method. Text being the text to display, Img being the index in the ImageList [or the bullet point if set to -1, or not specified at all], Normal is the colour when unselected, and Focus is the colour when selected.

  • Add(string Text)
  • Add(string Text, int Img)
  • Add(string Text, Color Normal, Color Focus)
  • Add(string Text, Color Normal, Color Focus, int Img)

And of course, the method to remove from the control, which has only one parameter, the Index of the control in the list.

  • Remove(int Index)

If you wanted to initiate the control, you can do so using one of the following constructors.

  • ListEx()
  • ListEx(ImageList imgs)

If you use the first constructor, the ImageList in initialized but has no content. you can set this at a later date, see the appendix for definitions. No lets get to some code.

C#
using Olib.Controls;
...
ListEx le = new ListEx();
//normal stuff so position and size control
le.Add("Text with default colours");
le.Add("Text with custom colours", Color.SteelBlue, Color.SkyBlue);
Controls.Add(le);

Notice above that I did not use le.Items.Add - this is due to what I described above. The Items.Add method is called in the ListEx.Add method. now then the example above does not specify an ImageList, so all the items will be given a bullet, regardless of whether or not an ImageList index is specified. You can add / change the image list on the fly, by using the Imgs property, or you can specify one in the constructor.

C#
using Olib.Controls;
...
ImageList Imgs = new ImageList();
Imgs.ImageSize = new Size(16,16);
Imgs.Images.Add(Image.FromFile("MyImg.bmp");
Imgs.TransparentColor = Color.FromArgb(255,0,255);
ListEx le = new ListEx(Imgs);
//normal stuff so position and size control
le.Add("Text with default colours", 0);
le.Add("Text with custom colours", Color.SteelBlue, Color.SkyBlue, -1);
Controls.Add(le);

Now that an image list has been specified, you can reference an index in the ImageList and it will be displayed, however, if you choose to use one of the Add methods without an img parameter, the image index is set to -1, which causes the bullet to be drawn, likewise, if you set -1 as the image index, a bullet will be drawn, as you can see by the example above.

Removing an item from the list is easier than adding, all you have to do is specify the index of the item, and the method does the rest.

C#
le.Remove(le.SelectedIndex);

That's all, easy. No lets move onto some of the other features. The context menu, you set all of the items to be added to the context menu to a MenuItem array, and the call the SetMenu(MenuItem[] ami) method.

C#
Menu[] menu = {new MenuItem("Some Menu Item"), 
    new MenuItem("Another Item")};
le.SetMenu(menu);

When a right mouse click is detected, it checks to see if it has a menu, if it does, it displays it, if it doesn't, nothing happens. Lastly, to change the colour of the line, all you have to do is set the LineColor property.

C#
le.LineColo = Color.Black;

Now lets examine the one and only event - PressIcon. This event is triggered when the user clicks on one of the bullets / icons. To handle he event, do the following.

C#
le.PressIcon += new ListEx.EventHandler(MyEventHandler);
...
public void MyEventHandler(int Index)
{
   ...
}

Just in case you hadn't noticed, there is only parameter in the delegate, int Index, this value is the index of the item on which the user pressed the bullet / icon. Now to change the content of an item, you use the ChangeItem and ChangeItemInfo methods.

So there you have it, its not exactly rocket science. Nice and simple to use. After all, im saving you the bother of programming the control yourself, I thought I may as well make it as easy as possible to use.

How ListEx Works

Editing Items

I would go on about how to edit the items in the listbox, but Nishant S has already made an article here. My code is slightly different to Nish's, but the principle is the same.

Context Menu

These are very easy to support, first of all, you need to capture the right click event, i chose to do this in the OnMouseUp event, as it makes more sense. Then all you need to do is create an object of type ContextMenu, assign it the MenuItem array, and call the Show method.

C#
if ((e.Button == MouseButtons.Right) && (!this.HasTextBox))
{
   if (this.menuItems != null)
   {
      ContextMenu cm = new ContextMenu(this.menuItems);
      cm.Show(this, PointToClient(Control.MousePosition));
   }
}

Drawing The Bullet

First of all - the items are drawn in the OnDrawMenuItem event, so this is what you need to override. to draw the bullet is very simple.

C#
Rectangle rect = new Rectangle();
rect.Y = e.Bounds.Y+7;
rect.X = e.Bounds.X+5;
rect.Width = 5;
rect.Height = 5;
e.Graphics.FillEllipse(new SolidBrush(Color.Black), rect);

the code above creates a rectangle object, whose xy co-ordinates is placed 5px from the left and 7px from the top of the item. To draw the icon is just as simple. The ImageList class has a Draw method.

C#
Rectangle rect = new Rectangle();
rect.Y = e.Bounds.Y+3;
rect.X = e.Bounds.X+2;
this.imgs.Draw(e.Graphics, rect.Left,rect.Top,
    ((ItemInfo)this.itemInfo[e.Index]).Img);

First of all a rectangle object is created, to specify the xy co-ordinates of the icon. Then the ImageList's Draw method is called, with the image index of the current item index as the final parameter.

Acknowledgements

  • Rama Krishna - Instructed me on using WndProc to capture the scrolling of the control.

  • David Stone - Risking his computer to test the control Finding no problems what-so-ever - he also assisted me by making the layout of the demo app with VS.NET.

Appendix

Methods

ListEx

ListEx()
ListEx(ImageList imgs)

This is the constructor. It has two overloads, the default one, which sets the image list to have no images, or the overload that enables you to specify an image list.

  • ImageList imgs - This is image list to be used when adding bullets
Add

Add(string text)<BR>Add(string text, int img)<BR>Add(string text, Color Normal, Color Focus)<BR>Add(string text, Color normal, Color Focus, int img)

This function adds an item to ListEx.

  • string text - The text to be displayed
  • int img - This is the index of the bullet icon in the image list, use -1 for a bullet point
  • Color Normal - The colour when the item is not in selection
  • Color Focus - The colour of the item when it is selected
ChangeItem

ChangeItem(int id, string text)

This function sets the 'Icon' which is actually any images file that can be read by the framework into an Image object.  It has one parameter

  • int id - this is the index of the item in the list
  • string text - this is the new text for the item
ChangeItemInfo

ChangeItemInfo(int id, Color Normal, Color Focus)

This sets the colours of an item.

  • int id - This is the Index of the item to be updated.
  • Color Normal - THe new colour for the item when not selected
  • Color Focus - The colour for the item when selected.
Remove

Remove(int id)

This removes an item from the listbox.

  • int id - The ID of the item to be removed
SetMenu

SetMenu(MenuItem[] menu)

Sets the context menu to be displayed on a right click.

  • MenuItem[] menu - This is an array of menu items to add to the context menu.

Properties

Imgs

This is the image list that will be used to draw Icon bullet points.

LineColor

This is the colour of the line drawn between items.


Events

PressIcon

This event is triggered when the user clicks on the bullet / icon. to add an event handler, just do the following

C#
le.PressIcon += new LixtEx.EventHandler(MyEventHandler);
...
public void MyEventHandler(int Index)
{
   ...
}

The int Index, is the index of the item which the icon was pressed.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United Kingdom United Kingdom
Nnamdi was born in 1986, all his life he has been into anything electrical (starting with plug sockets as soon as he could crawl) from there it moved onto dismantelling things to see what they looked like on the inside. Eventually this interest moved on to computers.

Started simple, with HTML, and moved on to JS. Then moved onto C#, he's all over the shop, doing programming(ish) type things, web designing [My Website] and graphics, although he cant draw to save his life.

He likes to use his computer, socialise with his mates, and laugh at his mates as they all try to apply for holiday jobs, while he has an office job in London, as a network administrator, all because he wowed his boss when he went there on work experience.

He goes by the alias 'TheEclypse'

Comments and Discussions

 
Questionhmmm bugs Pin
E! Ray K12-Mar-08 11:08
E! Ray K12-Mar-08 11:08 
GeneralProblem Pin
f.db4-Sep-06 0:30
f.db4-Sep-06 0:30 
GeneralBug had been found Pin
warmund30-May-06 2:03
warmund30-May-06 2:03 
NewsAdvanced list box and combo box Pin
brett5630-Nov-05 5:50
brett5630-Nov-05 5:50 
GeneralWell done, Nnamdi ! Pin
Nish Nishant8-Aug-02 14:58
sitebuilderNish Nishant8-Aug-02 14:58 
GeneralRe: Well done, Nnamdi ! Pin
Nnamdi Onyeyiri8-Aug-02 23:18
Nnamdi Onyeyiri8-Aug-02 23:18 
at first i was gonna make that bulleted textbox, but the thought of how to do it seemed somwhat confusing, so i decided to go for a sonork chat window like control instead Smile | :)


Suspicious | :suss: Email: theeclypse@hotmail.com   URL: http://www.onyeyiri.co.uk
Suspicious | :suss: "All programmers are playwrights and all computers are lousy actors."


GeneralNice Pin
Shog98-Aug-02 13:06
sitebuilderShog98-Aug-02 13:06 
GeneralRe: Nice Pin
Rama Krishna Vavilala8-Aug-02 14:40
Rama Krishna Vavilala8-Aug-02 14:40 
GeneralRe: Nice Pin
Shog98-Aug-02 14:50
sitebuilderShog98-Aug-02 14:50 
GeneralRe: Nice Pin
Nnamdi Onyeyiri8-Aug-02 23:18
Nnamdi Onyeyiri8-Aug-02 23:18 
GeneralRe: Nice Pin
Nnamdi Onyeyiri8-Aug-02 23:17
Nnamdi Onyeyiri8-Aug-02 23:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.