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) Smile

 image

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! Smile
Rahul

Share this post :