Elhendriks Elhendriks - 3 months ago 22
Vb.net Question

Display Colors in ComboBox from aRGB Value item

My problem is the following:

I have a Combobox filled with aRGB codes (extracted from an excel file), like this:

255, 149, 55, 39
255, 0, 176, 80
255, 0, 112, 192
...


My goal is to display a list of colors instead of their rgb code.
So, I tried to do this, unsuccessfully:

Private Sub CB_Color_DrawItem(ByVal sender As System.Object, ByVal e As DrawItemEventArgs) Handles CB_Color.DrawItem

If e.Index = -1 Then
Exit Sub
End If

Dim colBrush As Brush = New SolidBrush(Color.FromArgb(CB_Color.Items(e.Index)))
'Drawing rectangles for the color values
e.Graphics.DrawRectangle(New Pen(Brushes.Black), e.Bounds.Left + 2,
e.Bounds.Top + 2, 30, e.Bounds.Height - 5)
e.Graphics.FillRectangle(colBrush, e.Bounds.Left + 3, e.Bounds.Top + 3,
29, e.Bounds.Height - 6)

End Sub


This code doesn't change anything. I still have rbg codes in my combobox's list. Can anyone please tell me what's wrong whith this code?

Answer

You have several problems. As noted, if the Text is being drawn and your DrawItem code isnt drawing it, then DrawMode is probably not set to OwnderDrawFixed.

Then, once you say you will handle drawing the items, you have to handle all the drawing. That includes the Selected item highlighting, the background and the focus rectangle. The little color boxes you draw leave room to also display the text, so this will show how to do both.

Private Sub cbox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles cbox1.DrawItem
    If e.Index = -1 Then Return

    Dim thisText As String = cbox1.Items(e.Index).ToString()
    Dim thisColor As Color = CType(TypeDescriptor.GetConverter(GetType(Color)).
                                            ConvertFromInvariantString(thisText), 
                                            Color)
    ' use HeighLight when needed
    Dim foreclr As Color = If(e.State.HasFlag(DrawItemState.Selected),
                              SystemColors.HighlightText,
                              cbox1.ForeColor)

    e.DrawBackground()
    Using br As New SolidBrush(thisColor)
        e.Graphics.DrawRectangle(New Pen(Brushes.Black),
                                 e.Bounds.Left + 2, e.Bounds.Top + 2, 30,
                                 e.Bounds.Height - 5)
        e.Graphics.FillRectangle(br, e.Bounds.Left + 3, e.Bounds.Top + 3,
                     29, e.Bounds.Height - 6)

        Dim tRect = New Rectangle(e.Bounds.Left + 32, e.Bounds.Top + 2,
                                  e.Bounds.Width - 32, e.Bounds.Height - 4)
        TextRenderer.DrawText(e.Graphics, String.Format("255, {0:000}, {1:000}, {2:000}",
                                              thisColor.R, thisColor.G, thisColor.B),
                                              cbox1.Font, tRect, foreclr)
    End Using

    e.DrawFocusRectangle()

End Sub

The format of the ARGB string appears to be the InvariantString format which is used in all sorts of export and serialization. The code shows how to convert using it, but String.Split will work too. You will have to do the same when they make a selection to actually create a color from the text (or do all that up front and run off a List(Of Color))

The important thing is to check to see if the item is the Selected item and use the correct forecolor for any text you do draw. TheFocusRectangle is also shown.

There is plenty of room for both the text and a color swatch, but if you really do not want the ARGB text, just skip the DrawText code, and consider filling the entire rectangle with color rather than drawing a swatch:

enter image description here

Comments