Reputation: 119
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?
Upvotes: 1
Views: 1254
Reputation: 38875
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:
Upvotes: 4
Reputation: 44
Firstly in the combobox properties find the property called "DrawMode". Change this value to 'OwnerDrawFixed'. This is the value that indicates if the code or the operating system will handle the drawing.
Then you will need to add and change the following code:
Dim colorArray() As String = ComboBox1.Items(e.Index).ToString.Split(",")
Dim colBrush As Brush = New SolidBrush(Color.FromArgb(CInt(colorArray(0)), CInt(colorArray(1)), CInt(colorArray(2)), CInt(colorArray(3))))
We do this because the FromARGB only accepts integer values.
Upvotes: 2