-
1 Attachment(s)
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.
http://i45.tinypic.com/2i1mfcw.jpg
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.
vb.net Code:
Private _Items As ColorListBoxItemCollection
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public Overloads ReadOnly Property Items() As ColorListBoxItemCollection
Get
Return _Items
End Get
End Property
'The original items that the user will never see.
Private ReadOnly Property baseItems() As ObjectCollection
Get
Return MyBase.Items
End Get
End Property
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.
vb.net Code:
Protected Overrides Sub ClearItems()
MyBase.ClearItems()
_listBox.baseItems.Clear()
End Sub
Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As ColorListBoxItem)
MyBase.InsertItem(index, item)
_listBox.baseItems.Insert(index, item)
End Sub
Protected Overrides Sub RemoveItem(ByVal index As Integer)
MyBase.RemoveItem(index)
_listBox.baseItems.RemoveAt(index)
End Sub
Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As ColorListBoxItem)
MyBase.SetItem(index, item)
_listBox.baseItems(index) = item
End Sub
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% 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.
Enjoy!
-
Re: ListBox with custom items (colors, images, text alignment)
I'm having real trouble with this. :(
i added the control not a problem.
i added your code above and got errors. do you have that image as an example still that i could look at?
-
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)
-
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?
Thanks
Edit:
Here's how i managed to do it...for this thread here: http://www.vbforums.com/showthread.php?t=615255
vb.net Code:
Imports System.ComponentModel
Public Class ColorListBox
Inherits ListBox
Public Enum HotSpots As Integer
ITEM_IMAGE = 0
ICON1 = 1
ICON2 = 2
ICON3 = 3
DoubleClick = -1
End Enum
Public Event ClickedHotSpot(ByVal Index As Integer, ByVal Spot As HotSpots, ByVal Tag As String)
Public Shadows Sub ItemClickedSpot(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If e.Button = MouseButtons.Left Then
If e.Clicks = 1 Then
Select Case (e.Y - (Me.IndexFromPoint(e.X, e.Y) * Me.ItemHeight))
Case 22 To 63
Select Case e.X
Case 94 To 126
RaiseEvent ClickedHotSpot(Me.IndexFromPoint(e.X, e.Y), HotSpots.ICON1, Me.Items.Item(Me.IndexFromPoint(e.X, e.Y)).Tag)
Case 234 To 266
RaiseEvent ClickedHotSpot(Me.IndexFromPoint(e.X, e.Y), HotSpots.ICON2, Me.Items.Item(Me.IndexFromPoint(e.X, e.Y)).Tag)
Case 374 To 406
RaiseEvent ClickedHotSpot(Me.IndexFromPoint(e.X, e.Y), HotSpots.ICON3, Me.Items.Item(Me.IndexFromPoint(e.X, e.Y)).Tag)
End Select
End Select
Select Case (e.Y - (Me.IndexFromPoint(e.X, e.Y) * Me.ItemHeight))
Case 10 To 58
Select Case e.X
Case 14 To 56
RaiseEvent ClickedHotSpot(Me.IndexFromPoint(e.X, e.Y), HotSpots.ITEM_IMAGE, Me.Items.Item(Me.IndexFromPoint(e.X, e.Y)).Tag)
End Select
End Select
End If
If e.Clicks = 2 Then
RaiseEvent ClickedHotSpot(Me.IndexFromPoint(e.X, e.Y), HotSpots.DoubleClick, Me.Items.Item(Me.IndexFromPoint(e.X, e.Y)).Tag)
End If
End If
End Sub
'...
Implementing
vb.net Code:
Private Sub ColorListBox1_ClickedHotSpot(ByVal Index As Integer, ByVal Spot As ColorListBox.HotSpots, ByVal Tag As String) Handles ColorListBox1.ClickedHotSpot
MsgBox("Item number: " & Index + 0 & " - button: " & Spot.ToString & " TAG: " & Tag)
End Sub
Suggestions will be very welcome
-
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 As Integer = 0 To Me.Items.Count - 1
If Me.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
End If
' We've already found our item so stop looking
Exit For
End If
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.
-
2 Attachment(s)
Re: ListBox with custom items (colors, images, text alignment)
Good point...the square around the icons!
Thanks
(important, ItemHeight must be 70)
Here's how your class looks like in my implementation...i'm still twicking it so it's supposed to have a few bugs..
Here's how it's looking at the moment
-
Re: ListBox with custom items (colors, images, text alignment)
-
Re: ListBox with custom items (colors, images, text alignment)
Hey Nick.
Mind explaining me as a mini-guide how to make my Icon + Text ListBox?
Thanks.
-
Re: ListBox with custom items (colors, images, text alignment)
You have the source code, so why not take a look? If you have a specific question I'd be happy to answer it, but try to see it in the source code first, it's not very hard at all.
-
Re: ListBox with custom items (colors, images, text alignment)
i get error when i try to buld my solution with the control added
Quote:
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)
i have no idea how to use this
walkthrough please :
1 how to add the control ?
2 how to customize the control ?
3 where do i put the code of post 1, is it neccesary ?
-
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)
i added the control just as Nick described, but the control is not the one in post #1, but post #7.
-
Re: ListBox with custom items (colors, images, text alignment)
Quote:
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)
Quote:
Originally Posted by
TDQWERTY
Good point...the square around the icons!
Thanks
(important, ItemHeight must be 70)
Here's how your class looks like in my implementation...i'm still twicking it so it's supposed to have a few bugs..
Here's how it's looking at the moment
hello, there is a bug in your control. when you click and item then click another, the previous doesn't return to the normal state.
have you corrected this, can you tell me how?
-
Re: ListBox with custom items (colors, images, text alignment)
nice work
you thought about doing a listview version of this?
-
Re: ListBox with custom items (colors, images, text alignment)
Quote:
Originally Posted by
moeb1us
nice work
you thought about doing a listview version of this?
I recommend you look at the ObjectListView.
-
Re: ListBox with custom items (colors, images, text alignment)
i'm sorry but how do i add image into the item list. i can't do the below can you help me please. thanks
Dim img As Image
img = Image.FromFile("c:\temp\thumbnails\" & filename)
ColorListBox1.Items.Add(img)
-
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)
Quote:
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)
can you show me how, I try DirectCast as a String, not work...
-
Re: ListBox with custom items (colors, images, text alignment)
Quote:
Originally Posted by
rojaldearintok
can you show me how, I try DirectCast as a String, not work...
I'm want to say no because the source code is literally in front of you.
Code:
ColorListBoxItem1.Text
-
Re: ListBox with custom items (colors, images, text alignment)
okay thanks, i will try it...
-
Help with mouse cursor
hi
i just used your Colorlistbox and its great .
but i have one problem the mouse cursor is fixed on Wait and i cant change it not with the propery and not in code.
please help.
thanks.
-
Re: ListBox with custom items (colors, images, text alignment)
I tried but it's not working
need help sir, i really need this colorlistbox to my program
-
Re: ListBox with custom items (colors, images, text alignment)
Quote:
Originally Posted by
yvne
I tried but it's not working
need help sir, i really need this colorlistbox to my program
What error messages are you getting?
What where the steps you've tried?
-
1 Attachment(s)
Re: ListBox with custom items (colors, images, text alignment)
Quote:
Originally Posted by
JuggaloBrotha
What error messages are you getting?
What where the steps you've tried?
Attachment 110425
-
Re: ListBox with custom items (colors, images, text alignment)
Quote:
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)
Quote:
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...
Code:
Public Class ColorListBox
Inherits ListBox
#Region " Constructor "
Public Sub New()
Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
Me.DoubleBuffered = True
' .....
-
Re: ListBox with custom items (colors, images, text alignment)
Quote:
Originally Posted by
Edgemeal
Instead of setting DoubleBuffered on the Form try setting DoubleBuffered in the control(s) that flicker, like in the constructor of the ColorListBox class...
Code:
Public Class ColorListBox
Inherits ListBox
#Region " Constructor "
Public Sub New()
Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
Me.DoubleBuffered = True
' .....
Lol! Major D'OH. Why is my brain thinking this way? :lol:
Well, the double buffer works, but only if the listbox items don't have a really long bookmark and/or really long URL, which rarely happens lol...
I probably need to do a bit more of tweaking of the drawing event I guess.
-
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 :eek2:
-
Re: ListBox with custom items (colors, images, text alignment)
hi
how to change image size in item ListBox with custom items
please help me
-
Re: ListBox with custom items (colors, images, text alignment)
I removed the link to your email address. Posting that in a forum post is not a good idea, as it will be sucked up by a bot and you'll end up with lots of spam.
I'm not clear whether your question is regarding the custom listbox in this thread or in some other design. If it isn't based on the techniques discussed in this thread, then you should create your own thread over in the .NET forum for the question.