Enable wrap and change the color of Listbox items
Problem description> You have a Listbox where you have a lot of items which are quite large and won't fit inside the width of your listbox. You don't want to enable Horizontal Scroll bar, since you have don't want your users to keep scrolling left and right in order to view the items. Now if you are able to achieve this, you will notice that it looks pretty ugly since you won't be able to figure out the difference between a wrapped item, and another item. So, you decide to color each item in such a way that item #1 is green, #2 is yellow, #3 is cyan, #4 is green again, and so on...
Have a look at the figure below. The first one is the normal listbox. The 2nd listbox below is the customized version. I think the 2nd one looks much better (although I guess, the color selection could have been much better)
Anyway, lets see how you can code this in VB.NET...
I have created a new class called myListBox.vb
Public Class myListBox
Inherits ListBox
Private Sub myListBox_DrawItem( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawItemEventArgs _
) Handles Me.DrawItem
e.DrawBackground()
'Let's declare a brush, so that we can color the items that are added in the listbox.
Dim myBrush As Brush
If (e.State And DrawItemState.Selected) Then
e.Graphics.FillRectangle(Brushes.LightCyan, e.Bounds)
End If
'Determine the color of the brush to draw each item based on the index of the item to draw.
Select Case (e.Index) Mod 3
Case 0
myBrush = Brushes.Chocolate
Case 1
myBrush = Brushes.MediumSlateBlue
Case 2
myBrush = Brushes.Teal
End Select
' Draw the current item text based on the current Font and the custom brush settings.
e.Graphics.DrawString(Me.Items(e.Index), Me.Font, myBrush, _
New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height))
'If the ListBox has focus, draw a focus rectangle around the selected item.
e.DrawFocusRectangle()
End Sub
Public Sub New()
'This is super important. If you miss it... you won't be able to Draw the item.
'If you make it OwnerDrawFixed you won't be able to measure the item.
Me.DrawMode = DrawMode.OwnerDrawVariable
End Sub
Private Sub myListBox_MeasureItem( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.MeasureItemEventArgs _
) Handles Me.MeasureItem
Dim g As Graphics = e.Graphics
'We will get the size of the string which we are about to draw,
'so that we could set the ItemHeight and ItemWidth property
Dim size As SizeF = g.MeasureString(Me.Items.Item(e.Index).ToString, Me.Font, _
Me.Width - 5 - SystemInformation.VerticalScrollBarWidth)
e.ItemHeight = CInt(size.Height) + 5
e.ItemWidth = CInt(size.Width) + 5
End Sub
End Class
I have created a new form to test my listbox. Here is the code for ListBoxDemo form (Written in VS 2005 - VB.NET)
Public Class ListBoxDemo
Dim clbActualCheckedListBox As New ListBox
Dim mclbMyCheckedListBox As New myListBox
Private Sub CheckedListBoxDemo_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Height = 420
'Normal List Box
With clbActualCheckedListBox
.Top = 10
.Left = 10
.Width = 400
.Height = 150
.Font = New Font("Microsoft Sans Serif", 10, FontStyle.Bold)
.HorizontalScrollbar = True
.Items.Add("1")
.Items.Add("2")
.Items.Add("3 => This is a very very very very very very very very very very very very very very looooooooong item")
.Items.Add("4")
.Items.Add("5 => And this one is another very very very very very very very looong string")
.Items.Add("6")
End With
'Customized List Box
With mclbMyCheckedListBox
.Top = 180
.Left = 10
.Width = 400
.Height = 200
.Font = New Font("Microsoft Sans Serif", 10, FontStyle.Bold)
.HorizontalScrollbar = False
.Items.Add("1")
.Items.Add("2")
.Items.Add("3 => This is a very very very very very very very very very very very very very very looooooooong item")
.Items.Add("4")
.Items.Add("5 => And this one is another very very very very very very very looong string")
.Items.Add("6")
End With
Me.Controls.Add(clbActualCheckedListBox)
Me.Controls.Add(mclbMyCheckedListBox)
End Sub
End Class
I hope this helps!
Rahul
Share this post : |