
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.
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.
using Olib.Controls;
...
ListEx le = new ListEx();
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.
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);
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.
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.
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.
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.
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.
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.
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.
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
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
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. |