Listboxs with multicolored items

I've got an application that will add action items to a listbox. Some of the items are higher priority (Red) and others are not (Yellow). Is there a way to put both colors into a listbox

Answer this question

Listboxs with multicolored items

  • Alexandrea

    A single column Listview in Detail view would be the simpliest


  • Tammt

    here is a sample to draw custom colors on each item in a standard listbox...you of course will have to keep track of you priority items to draw those indexes a specific color...

    Dim MyBrush() As System.Drawing.Brush = New System.Drawing.Brush() {Brushes.Blue, Brushes.Black, Brushes.DarkGreen, Brushes.Coral, Brushes.DarkGray, Brushes.DarkMagenta, _

    Brushes.Brown, Brushes.Aqua, Brushes.Gold, Brushes.Orange, Brushes.RoyalBlue}

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    For x As Integer = 1 To 10

    Me.ListBox1.Items.Add("Item" & x)

    Next

    End Sub

    Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem

    e.Graphics.DrawString(Me.ListBox1.Items(e.Index).ToString, Me.Font, MyBrush(e.Index), e.Bounds.X, e.Bounds.Y)

    End Sub



  • Dave Waterworth

    Set the draw mode of the listbox to ownerdraw

  • MtEvans

    If I copy this sample to my project It doesn't work. Items haven't any colors. What I have to do else

    Thank You.


  • cedubose

    Waltari wrote:
    I guess I'm still missing something here. How is the data added to the listbox with this method

    With the Add method, as usual. I'll flesh out the example I posted above and that might make it clearer.

    First, we have a simple class, PriorityListBoxItem that hold the description and priority. This class also has an Enum for the Priority values. Note that the New constructor allows you to pass in the values for the properties. In a more 'real world' application, you might populate here from a query, datarow from a query, an XmlElement, or any other source of data.

    Public Class PriorityListBoxItem

    Public Enum PriorityValue
    LowPriority
    HighPriority
    End Enum

    Private _description As String
    Private _priority As PriorityValue

    Public Sub New(ByVal itemDescription As String, ByVal itemPriority As PriorityValue)
    Description = itemDescription
    Priority = itemPriority
    End Sub

    Public Property Description() As String
    Get
    Return _description
    End Get
    Set(ByVal value As String)
    _description = value
    End Set
    End Property

    Public Property Priority() As PriorityValue
    Get
    Return _priority
    End Get
    Set(ByVal value As PriorityValue)
    _priority = value
    End Set
    End Property

    End Class

    Next, in the form's Load event, we populate the listbox. In this simple example I do a loop that sets the priority High for even values and Low for odd values. In the real world, this would be done from your data source rather than a hard code. A new instance of the PriorityListBoxItem class is added to the listbox on each iteration of the loop. Remember that in .NET you're not limited to only strings in a listbox, you can store objects of any type. The only thing that you have to be aware of is your memory and performance may be impacted in some cases.

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    For x As Integer = 1 To 10
    If x Mod 2 = 0 Then
    ListBox1.Items.Add(New PriorityListBoxItem("Item" & x, _
    PriorityListBoxItem.PriorityValue.HighPriority))
    Else
    ListBox1.Items.Add(New PriorityListBoxItem("Item" & x, _
    PriorityListBoxItem.PriorityValue.LowPriority))
    End If
    Next
    End Sub

    Finally, you would have the routine I posted earlier that used the DrawItem event to set the display string and it's color.

    If you wanted to do this object in a ListBox trick without the owner draw, then you would need to override the ToString function of the class since otherwise you would get the default object moniker that .NET object base class provides for this method. So, in my example, you would add the following routine to the class to return the Description property instead of the default string.

    Public Overrides Function ToString() As String
    Return Description
    End Function



  • rod_r

    OK.Thank you very much, DMan1.
  • Michael Schreyer

    Thanks everyone. The code appears to be working perfectly.
  • Hamann Heinz

    I guess I'm still missing something here. How is the data added to the listbox with this method
  • JohnSLG

    It seems you are one step ahead of me, Frank......I was just about to say that. I'm working on exactly that sort of thing at the moment.

    So I will add, you can also draw lines, circles and images as appropriate for the entry (e.g. a nice red flag...). Here's a quick screenshot of what I'm working on at present...

    http://www.playinthesoup.com/soup/misc/ownerdrawtreelist.png



  • dgaynes

    DMan1 wrote:

    here is a sample to draw custom colors on each item in a standard listbox...you of course will have to keep track of you priority items to draw those indexes a specific color...

    Dim MyBrush() As System.Drawing.Brush = New System.Drawing.Brush() {Brushes.Blue, Brushes.Black, Brushes.DarkGreen, Brushes.Coral, Brushes.DarkGray, Brushes.DarkMagenta, _

    Brushes.Brown, Brushes.Aqua, Brushes.Gold, Brushes.Orange, Brushes.RoyalBlue}

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    For x As Integer = 1 To 10

    Me.ListBox1.Items.Add("Item" & x)

    Next

    End Sub

    Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem

    e.Graphics.DrawString(Me.ListBox1.Items(e.Index).ToString, Me.Font, MyBrush(e.Index), e.Bounds.X, e.Bounds.Y)

    End Sub

    If I copy this sample to my project It doesn't work. Items haven't any colors. What I have to do else

    Thank You


  • Kamen

    You'll have to owner draw a standard listbox. Here's a link that describes how to do it in C# but if you Google around for it you might find a version in VB.

    Other alternatives would be to use a 3rd party list box that has this feature or use Treeview or Listview controls if either of them will work for the look and feel you want.



  • Mark Benningfield

    I've tried the owner draw option, but when I change the color in the draw event the entire list gets rewritten as the new color.
  • Matt A

     DMan1 wrote:

    here is a sample to draw custom colors on each item in a standard listbox...you of course will have to keep track of you priority items to draw those indexes a specific color...

    I'm still being amazed at how much easier some things are to do under VB.NET than they were in VB6. That's what's great about these forums, you can learn something new just about every day.

    To add to your example, the Listbox items are objects, not strings, so you could put the object as an item in the listbox and use this object to determine the correct brush and text in the DrawItem routine, something like this:

    Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem
        Dim TextBrush As System.Drawing.Brush
        Dim ListItem As PriorityListBoxItem = TryCast(ListBox1.Items(e.Index), PriorityListBoxItem)
        Select Case ListItem.Priority
            Case PriorityListBoxItem.PriorityValue.HighPriority
                TextBrush = Brushes.Red
            Case PriorityListBoxItem.PriorityValue.LowPriority
                TextBrush = Brushes.DarkGoldenrod
            Case Else
                TextBrush = Brushes.Black
        End Select
        e.Graphics.DrawString(ListItem.Description, Me.Font, TextBrush, e.Bounds.X, e.Bounds.Y)
    End Sub



  • Listboxs with multicolored items