If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

ListBox with custom items (colors, images, text alignment)

Hey,

Here is a very simple owner-drawn ListBox control that allows you to specify a Color and Image for each item. It uses a very simple method to only allow items of a specific type (and not all Objects as usual) which is easily extended.

I know you could just use a ListView for this, but I came across this method when creating a different control (a 'large item' listbox that looks like the Downloads window in FireFox) and decided to share it, because it is conceptually easy and allows you to extend the items much more. For example, there's nothing stopping you to give each item it's own Font or something.

As a 'bonus' there is also a TextAlign property which allows you to align the text of all items to whichever side you want (MiddleLeft in the image).

How it works:

The ColorListBox class inherits ListBox, and overloads the Items property. Instead of returning MyBase.Items, it returns its own ColorListBoxItemCollection.
The original base items are then returned by a (private) property baseItems.

The ColorListBoxItemCollection inherits System.Collections.ObjectModel.Collection(Of ColorListBoxItem) and overrides the Set/Remove/InsertItem and ClearItems methods. In those methods, it adds the item to it's collection but also adds the item to the baseItems property of the owner ColorListBox. This is necessary because the ColorListBox won't draw any items in your own custom collection; only those in the MyBase.Items collection.

Finally, the ColorListBox is owner drawn, so it overrides the OnDrawItem method. The listbox actually wants to draw the original items, but I simply force it to use the items from my own collection (by using their index), and draw them with the correct color and possibly with an image.

As I said, this is the 'base' for a different ListBox control which I'll hopefully also complete shortly.

I am not 100&#37; sure whether this method will always work (I am afraid the baseItems and Items might become 'de-synchronised' for some reason for example), but I hope it will work fine.

Re: ListBox with custom items (colors, images, text alignment)

You don't need to add any code, the code is all in the vb file. If you added the control without problems then all you need to do is build the project and it will be in your toolbox like any other control.

Re: ListBox with custom items (colors, images, text alignment)

I'd like to detect clicked regions in each and every item from the ColorListBox, but i dunno what has to be done in this class of yours to accomplish that. Wouldn't you have any idea would you?
Maybe creating an other method "ItemClickedSpot"? But then, how?

Re: ListBox with custom items (colors, images, text alignment)

Ok, a couple of suggestions:

1. Instead of handling the MouseDown event of your own class, you should generally override the OnMouseDown method instead. It has the same end effect, but there are a few reasons why that approach is better (I can't remember any though...)

2. You seem to be hardcoding the 'hotspots' by their X and Y values. What if you decide to shift an icon 2 pixels? Then you'd need to change your code... Not very desirable I think!

What you can do instead is make use of the fact that my ListBox is using custom items; the ColorListBoxItem class. As of now, it has only three properties (Text, Color and Image), but you can add to that of course.

Why not add a few Rectangle properties that represent your hotspots. You would have a property for every hotspot (Icon1, Icon2, Icon3, ItemImage, etc), representing the bounds of that hotspot.
Then, in your MouseDown event (or OnMouseDown override, see point 1), you can retrieve the item that the mouse is clicked on, and then check if the click location is inside any of the hotspots:

vb.net Code:

For i AsInteger = 0ToMe.Items.Count - 1

IfMe.GetItemRectangle(i).Contains(e.Location)Then

' This is your item

Dim item As ColorListBoxItem = Me.Items(i)

If item.Icon1.Contains(e.Location)Then

RaiseEvent ClickedHotSpot(... Icon1)

ElseIf item.Icon2.Contains(e.Location)Then

RaiseEvent ClickedHotSpot(... Icon2)

'etc

EndIf

' We've already found our item so stop looking

ExitFor

EndIf

Next

Now, if you want to shift/enlarge/whatever Icon2 (for example), you just change the Icon2 Rectangle property of the item, and your code still works.

You can do the same in the OnMouseMove method and OnMouseUp method to simulate a button; change the border of the icon when the mouse is moving over the item, change it another way when the mouse is down, and change it back when the mouse is up.
How you're going to implement that depends on how you're drawing the icons. I suppose you have edited the OnDrawItem method so that it draws the icons too? By the way, if you have, you can make use of the Icon1, Icon2, etc properties too. Just draw the icon using those Rectangles.

Re: ListBox with custom items (colors, images, text alignment)

i get error when i try to buld my solution with the control added

Error 1 'down' is not a member of 'Resources'. ColorListBox2.vb 128 34
Error 2 'up' is not a member of 'Resources'. ColorListBox2.vb 134 34
Error 3 Type 'OwnerDrawnListBox' is not defined. ColorListBox2.vb 446 14
Error 4 'CreateGraphics' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 456 29
Error 5 'ItemHeight' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 457 9
Error 6 'Font' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 457 50
Error 7 'Items' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 464 25
Error 8 'SelectedIndex' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 464 34
Error 9 sub 'OnPaint' cannot be declared 'Overrides' because it does not override a sub in a base class. ColorListBox2.vb 484 29
Error 10 'OffScreen' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 491 57
Error 11 'BackColor' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 492 49
Error 12 'ClientRectangle' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 492 64
Error 13 'VScrollBar' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 498 17
Error 14 'VScrollBar' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 498 41
Error 15 Name 'DrawCount' is not declared. ColorListBox2.vb 498 63
Error 16 'Items' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 501 21
Error 17 'Font' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 502 33
Error 18 'Items' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 504 38
Error 19 'SelectedIndex' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 507 20
Error 20 'ClientSize' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 508 98
Error 21 'VScrollBar' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 508 124
Error 22 'VScrollBar' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 508 147
Error 23 'ItemHeight' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 508 172
Error 24 'ForeColor' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 513 29
Error 25 'Items' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 516 40
Error 26 'ItemHeight' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 517 line 24
Error 27 'OffScreen' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 521 line 30
Error 28 sub 'OnPaintBackground' cannot be declared 'Overrides' because it does not override a sub in a base class. ColorListBox2.vb 528 line 29
Error 29 'ClientSize' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 529 line 62
Error 30 'ClientSize' is not a member of 'color_listbox.FontListBox'. ColorListBox2.vb 529 line 87

Re: ListBox with custom items (colors, images, text alignment)

Just add the file to your project and build the solution, then it should come up in the toolbox as usual. Drag it to your form and add items via the Items property.
You don't need the code of post 1, that is already in the control, I just posted it to clarify how it works in case anyone was interested.

Re: ListBox with custom items (colors, images, text alignment)

Originally Posted by NickThissen

Just add the file to your project and build the solution, then it should come up in the toolbox as usual. Drag it to your form and add items via the Items property.
You don't need the code of post 1, that is already in the control, I just posted it to clarify how it works in case anyone was interested.

i downloaded : colorlistbox.vb
how do i add it from vb.net ?
you also said "then build the solution" what is that supposed to mean ? how ?
project (on the menu) then what ?
walkthrough please

Re: ListBox with custom items (colors, images, text alignment)

See your Solution Explorer toolwindow. Rightclick the project you want it to be used in and select "Add - Add Existing File". Choose the .vb file and add it. Then go to the Build menu and select Build solution (or rightclick the project and select Build from there). If the build succeeds (you can see this in the output window) when there are no errors then the control should appear at the top of the toolbox.

Re: ListBox with custom items (colors, images, text alignment)

Re: ListBox with custom items (colors, images, text alignment)

how do you check for duplicate items, I'm adding folder path, i want to check for duplicate, I'm using this code, but there is a problem, Its say "Value of type 'String' cannot be converted to 'ColorListBoxItem'.", it usually work on the normal listbox but this one is not working

If fFolder.ShowDialog = DialogResult.OK Then
If Not lstFolder.Items.Contains(fFolder.SelectedPath) Then
lstFolder.Items.Add(fFolder.SelectedPath, Color.Black, My.Resources.FolderHorizontal)
End If
End If

Re: ListBox with custom items (colors, images, text alignment)

Originally Posted by rojaldearintok

how do you check for duplicate items, I'm adding folder path, i want to check for duplicate, I'm using this code, but there is a problem, Its say "Value of type 'String' cannot be converted to 'ColorListBoxItem'.", it usually work on the normal listbox but this one is not working

If fFolder.ShowDialog = DialogResult.OK Then
If Not lstFolder.Items.Contains(fFolder.SelectedPath) Then
lstFolder.Items.Add(fFolder.SelectedPath, Color.Black, My.Resources.FolderHorizontal)
End If
End If

If you look at the ColorListBoxItem class, you will see there is a Text property that you can use.

Re: ListBox with custom items (colors, images, text alignment)

Originally Posted by yvne

Not sure why it's erroring like that in the ToolBox, when I have this control in my project's it shows at the very top (once I've compiled the project) and it has a purple gear icon. Maybe you could try removing it from your toolbox, recompile your project and see if it shows up at the very top.

Regardless of the toolbox issue, when you manually add it to a form does it still function normally?

Re: ListBox with custom items (colors, images, text alignment)

Hi there.
Sorry for necroing this thread, but I have a question about this awesome custom control.

I'm using this custom control to list visited websites that were bookmarked by the user. I've coded a procedure, which allows the user to see the URL corresponding to the bookmark, which is being hovered by the mouse.

Everything works perfectly, but the control flickers like there's no tomorrow ...
Is there a way to remove or at least considerably reduce the flickering? I've tried the doublebuffered property on the form itself, but that doesn't work.

Re: ListBox with custom items (colors, images, text alignment)

Originally Posted by Simbiose

Everything works perfectly, but the control flickers like there's no tomorrow ...
Is there a way to remove or at least considerably reduce the flickering? I've tried the doublebuffered property on the form itself, but that doesn't work.

Instead of setting DoubleBuffered on the Form try setting DoubleBuffered in the control(s) that flicker, like in the constructor of the ColorListBox class...

Re: ListBox with custom items (colors, images, text alignment)

FML! You can't set the listbox item image on run-time? You can only do it be using the Properties Window of the listbox?
The data is loaded into the listbox from a fed datatable, so I can only define the images for each item on run-time ............
Any work around for this?

Edit* *Hard facekeyboard* You CAN set the listbox item image on run-time... what was happening to me, was that I have a textbox that has a textchanged event that handles the way that the adapter feeds the datatable and consequently the datatable would be in charge of adding items to the listbox.
So whenever I loaded the form, the textbox would add items to the listbox, instead of the load event of the form (which was where I was handling the item image adding).
All I had to do was add the images on the textbox event