Introduction
Ever wanted to have a lightweight list box control for your Windows Forms application to list custom items, for example, to list picture albums in a nice way - with an album front image, album name and details, like how many photos in an album, etc.? I was always disappointed with DataGridView
, it's a good component in some cases, but usually you just need a nice, clear list, that's why I came up with this extended exListBox
.
Background
I think everybody has noticed that the standard Windows Forms ListBox
item is an object
type, not a string
. If you will try to pass your business object to ListBox.Items
, it won't understand how you would like it to be displayed and will just print out your object's class name. But there's a solution - to override the OnDrawItem
event, and placing your own drawing procedure. By the way, I was trying to keep the code as short as possible and as easy to understand as possible, so in that way, I didn't implemented real data binding, some constructors/properties aren't in the right places, and so on.
Using the code
There are two classes that you'll need - exListBox
and exListBoxItem
. The first one is derived from ListBox
just to override the OnDrawItem
event, though you could do this without creating a separate class, by simply handling the onDrawItem
event in your form source code, but if you'll use the extended ListBox
on several forms, it's better for sure to place the code on a separate code file. The second class (exListBoxItem
) is created from scratch, it has its drawing procedure and the elements that need to show up on the list. On the current example, an item contains an image, item title, and item details, but you can easily extend exListBoxItem
with your own code and have your own elements.
Adding new items is easy:
Image myImage = new Image.FromFile("image.jpg");
int id = 1;
myExListBox.Items.Add(new exListBoxItem(id, "title", "details", myImage));
As you can see, I've placed one more variable to exListBoxItem
- id
, it should help you bind exListBox
with your databases. I didn't make any real data binding to keep the code small, easy to understand, and in an easy edit-to-fit-your-needs form.
ExListBoxItem selected = (myExListBoxItem)myExListBox.SelectedItem;
int id = selected.Id;
If you would like to change the fonts used in item drawing, or the image size, you should call the new constructor for your exListBox
:
myExListBox = new exListBox(new Font(this.Font, FontStyle.Bold),
this.Font, new Size (100, 80),
StringAlignment.Near, StringAlignment.Near);
If you change the drawing procedure, you should take care of a few things. First of all, you need to check if the item which you will be drawing is selected or not. As you can see from the method title, I’m taking info about the selected item in DrawItemEventArgs
. Here, I can find if the item is selected or not and the item bounds where I must draw the item. All other arguments are necessary only in my case. If your exListBoxItem
contains other elements, it may look a bit different.
public void drawItem(DrawItemEventArgs e, Padding margin,
Font titleFont, Font detailsFont, StringFormat aligment,
Size imageSize)
{
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
}
else
{
}
e.Graphics.DrawLine(Pens.DarkGray, e.Bounds.X, e.Bounds.Y,
e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
...
e.DrawFocusRectangle();
}
History