Here's a ComboBox that displays Colors from the Color class, it even includes a square in the drop down showing the color as well as the name.
See post #5 and #6 for the control's code.
Here some examples of using it:
Code:
'Use defaults
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ccb As New ColorComboBox()
ccb.Location = New Point(5I, 5I)
Me.Controls.Add(ccb)
End Sub
'Includes SystemColors
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ccb As New ColorComboBox(False, True)
ccb.Location = New Point(5I, 5I)
Me.Controls.Add(ccb)
End Sub
'Use custom list of colors
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ccb As New ColorComboBox(New Color() {Color.Black, Color.White, Color.Blue, Color.Red})
ccb.Location = New Point(5I, 5I)
Me.Controls.Add(ccb)
End Sub
Last edited by JuggaloBrotha; Sep 23rd, 2008 at 12:55 PM.
Currently using VS 2015 Enterprise on Win10 Enterprise x64.
Very nice class... Thanks for sharing it with us, JB.
Is a FontComboBox (similar to the one used in MS Word) class on its way too?
I could, I haven't had a project where I need one but it shouldn't be too hard to do.
Also, I'm going to throw this out to everyone: Is it possible to override the Items.Add() method of a ComboBox/ListBox? This ColorComboBox.Items.Add() still accepts a parameter that's of type Object, I would like to override it so that it can only accept a Color.
I'm going to start making a FontComboBox soon and it would be nice to have FontComboBox.Items.Add() only accept a Font, not Object.
Currently using VS 2015 Enterprise on Win10 Enterprise x64.
Option Explicit On
Option Strict On
Option Infer Off
Imports System.ComponentModel
<ToolboxItem(True), ToolboxBitmap(GetType(ColorComboBox), "ColorComboBox.bmp"), System.Diagnostics.DebuggerStepThrough()> _
Public Class ColorComboBox
Inherits System.Windows.Forms.ComboBox
Private _ColorList As List(Of Color)
Private _SortAlphabetical As Boolean
Private _IncludeTransparent As Boolean
Private _IncludeSystemColors As Boolean
Private _MinimumSize As New Size(60I, 21I)
#Region " Constructors "
Public Sub New()
Call PreInitialize()
Call Initialize()
End Sub
Public Sub New(ByVal IncludeTransparent As Boolean, ByVal IncludeSystemColors As Boolean, ByVal Alphabetical As Boolean)
_IncludeTransparent = IncludeTransparent
_IncludeSystemColors = IncludeSystemColors
_SortAlphabetical = Alphabetical
Call PreInitialize()
Call Initialize()
End Sub
Public Sub New(ByVal TheColors() As Color)
Call PreInitialize()
_ColorList.AddRange(TheColors)
Call SetValues()
End Sub
#End Region
#Region " Properties "
<Description("Sort the colors in the DropDown alphabetically"), DefaultValue(False), Category("Colors")> _
Public Property SortAlphabetically() As Boolean
Get
Return _SortAlphabetical
End Get
Set(ByVal value As Boolean)
If _SortAlphabetical <> value Then
_SortAlphabetical = value
Call SetValues()
End If
End Set
End Property
<Description("Include the transparent color in the DropDown"), DefaultValue(False), Category("Colors")> _
Public Property IncludeTransparent() As Boolean
Get
Return _IncludeTransparent
End Get
Set(ByVal value As Boolean)
If _IncludeTransparent <> value Then
_IncludeTransparent = value
If value = True Then
If _ColorList.Contains(Color.Transparent) = False Then
_ColorList.Add(Color.Transparent)
Call SetValues()
End If
Else
If _ColorList.Contains(Color.Transparent) = True Then
_ColorList.Remove(Color.Transparent)
Call SetValues()
End If
End If
End If
End Set
End Property
<Description("Include the system colors in the DropDown"), DefaultValue(False), Category("Colors")> _
Public Property IncludeSystemColors() As Boolean
Get
Return _IncludeSystemColors
End Get
Set(ByVal value As Boolean)
If _IncludeSystemColors <> value Then
_IncludeSystemColors = value
If value = True Then
Call AddSystemColors()
Else
Call RemoveSystemColors()
End If
End If
End Set
End Property
<Browsable(False), EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), _
DefaultValue(False)> _
Public Shadows ReadOnly Property Sorted() As Boolean
Get
Return False
End Get
End Property
<Browsable(False), EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), _
DefaultValue(Windows.Forms.DrawMode.OwnerDrawFixed)> _
Public Shadows ReadOnly Property DrawMode() As System.Windows.Forms.DrawMode
Get
Return System.Windows.Forms.DrawMode.OwnerDrawFixed
End Get
End Property
<Browsable(False), EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), _
DefaultValue(System.Windows.Forms.ComboBoxStyle.DropDownList)> _
Public Shadows ReadOnly Property DropDownStyle() As System.Windows.Forms.ComboBoxStyle
Get
Return System.Windows.Forms.ComboBoxStyle.DropDownList
End Get
End Property
<Browsable(False), EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), _
DefaultValue("60, 21")> _
Public Shadows ReadOnly Property MinimumSize() As System.Drawing.Size
Get
Return _MinimumSize
End Get
End Property
#End Region
#Region " Methods "
<Description("Add a color to the DropDown")> _
Public Sub Add(ByVal Item As Color)
If _ColorList.Contains(Item) = False Then
_ColorList.Add(Item)
Call SetValues()
End If
End Sub
<Description("Add an array of colors to the DropDown")> _
Public Sub AddRange(ByVal Items() As Color)
For Each clr As Color In Items
If _ColorList.Contains(clr) = False Then _ColorList.Add(clr)
Next clr
Call SetValues()
End Sub
<Description("Removes a color from the DropDown")> _
Public Sub Remove(ByVal Item As Color)
If _ColorList.Contains(Item) = False Then
_ColorList.Remove(Item)
Call SetValues()
End If
End Sub
Public Sub RemoveRange(ByVal Items() As Color)
For Each clr As Color In Items
If _ColorList.Contains(clr) = False Then _ColorList.Remove(clr)
Next clr
Call SetValues()
End Sub
#End Region
#Region " Initialize, SetValues "
Private Sub PreInitialize()
MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
MyBase.DropDownStyle = ComboBoxStyle.DropDownList
MyBase.Sorted = False
MyBase.MinimumSize = _MinimumSize
_ColorList = New List(Of Color)
End Sub
Private Sub Initialize()
If DesignMode = False Then
Dim CurrColor As Color
_ColorList.Clear()
For Each aColorName As String In System.Enum.GetNames(GetType(System.Drawing.KnownColor))
CurrColor = Color.FromName(aColorName)
If _IncludeSystemColors = True Then
If _IncludeTransparent = True Then
If _ColorList.Contains(CurrColor) = False Then _ColorList.Add(CurrColor)
Else
If CurrColor <> Color.Transparent AndAlso _ColorList.Contains(CurrColor) = False Then _ColorList.Add(CurrColor)
End If
Else
If _IncludeTransparent = True Then
If CurrColor.IsSystemColor = False AndAlso _ColorList.Contains(CurrColor) = False Then _ColorList.Add(CurrColor)
Else
If CurrColor.IsSystemColor = False AndAlso CurrColor <> Color.Transparent AndAlso _ColorList.Contains(CurrColor) = False Then _ColorList.Add(CurrColor)
End If
End If
Next aColorName
Call SetValues()
End If
End Sub
Private Sub SetValues()
Me.Items.Clear()
If DesignMode = False Then
If _SortAlphabetical = False Then
_ColorList.Sort(AddressOf SortColors)
Else
_ColorList.Sort(AddressOf SortAlphabetical)
End If
Me.Items.Clear()
For Counter As Integer = 0I To _ColorList.Count - 1I
Me.Items.Add(_ColorList(Counter))
Next Counter
End If
End Sub
#End Region
#Region " AddSystemColors, RemoveSystemColors "
Private Sub AddSystemColors()
If DesignMode = False Then
Dim CurrColor As Color
For Each aColorName As String In System.Enum.GetNames(GetType(System.Drawing.KnownColor))
CurrColor = Color.FromName(aColorName)
If CurrColor.IsSystemColor = True AndAlso _ColorList.Contains(CurrColor) = False Then _ColorList.Add(CurrColor)
Next aColorName
Call SetValues()
End If
End Sub
Private Sub RemoveSystemColors()
If DesignMode = False Then
For Counter As Integer = _ColorList.Count - 1I To 0I Step -1I
If _ColorList(Counter).IsSystemColor = True Then _ColorList.RemoveAt(Counter)
Next Counter
'For Each clr As Color In _ColorList
' If clr.IsSystemColor = True Then _ColorList.Remove(clr)
'Next clr
Call SetValues()
End If
End Sub
#End Region
Last edited by JuggaloBrotha; Jul 29th, 2009 at 07:57 PM.
Currently using VS 2015 Enterprise on Win10 Enterprise x64.
#Region " Overrides Sub "
Protected Overrides Sub OnFontChanged(ByVal e As System.EventArgs)
Select Case True
Case Me.Font.SizeInPoints > 12.0F : Me.Font = New Font(Me.Font.FontFamily, 12.0F, Me.Font.Style)
Case Me.Font.SizeInPoints < 8.0F : Me.Font = New Font(Me.Font.FontFamily, 8.0F, Me.Font.Style)
End Select
End Sub
Protected Overrides Sub onDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
'Private Sub ComboBox_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles Me.DrawItem
e.DrawBackground()
e.DrawFocusRectangle()
If e.Index >= 0I Then
' Get the Color object from the Items list
Dim aColor As Color = CType(Me.Items(e.Index), Color)
' get a square using the bounds height
Dim rect As Rectangle = New Rectangle(5I, e.Bounds.Top + 2I, e.Bounds.Height - 3I, e.Bounds.Height - 5I)
Dim br As Brush = If((e.State And DrawItemState.Selected) = DrawItemState.Selected, Brushes.White, Brushes.Black)
' draw a rectangle and fill it
e.Graphics.DrawRectangle(New Pen(aColor), rect)
e.Graphics.FillRectangle(New SolidBrush(aColor), rect)
' draw a border
rect.Inflate(1I, 1I)
e.Graphics.DrawRectangle(Pens.Black, rect)
' draw the Color name
e.Graphics.DrawString(aColor.Name, Me.Font, br, e.Bounds.Height + 5I, ((e.Bounds.Height - Me.Font.Height) \ 2I) + e.Bounds.Top)
End If
End Sub
#End Region
#Region " SortColors "
Private Function SortColors(ByVal x As Color, ByVal y As Color) As Integer
Dim huecompare As Integer = x.GetHue.CompareTo(y.GetHue)
Dim satcompare As Integer = x.GetSaturation.CompareTo(y.GetSaturation)
Dim brightcompare As Integer = x.GetBrightness.CompareTo(y.GetBrightness)
Select Case True
Case huecompare <> 0I : Return huecompare
Case satcompare <> 0I : Return satcompare
Case brightcompare <> 0I : Return brightcompare
Case Else : Return 0I
End Select
End Function
Private Function SortAlphabetical(ByVal x As Color, ByVal y As Color) As Integer
Return x.Name.CompareTo(y.Name)
End Function
#End Region
End Class
Last edited by JuggaloBrotha; Jul 29th, 2009 at 07:57 PM.
Currently using VS 2015 Enterprise on Win10 Enterprise x64.
Just an fyi, I've recently noticed that this code works flawlessly when running in VS 2005 and VS 2008 on a winXP computer, but running it in VS 2005 and VS 2008 on a Vista computer you get an "Invalid Parameter" exception in the DrawItem event, this line fails:
Both Visual Studios are fully up to date, same with the .Net Frameworks and both the XP comp and Vista comp have all of the updates installed respectively too, anyone have and idea(s)? Other than Vista sucks (which I already know)
Currently using VS 2015 Enterprise on Win10 Enterprise x64.
I get the Invalid Parameter exception too, on XP Media Center Edition 2005.
The Invalid Parameter exception occurs when you dispose a brush that is set to any of the default brushes in the Brushes enumeration, exactly what you are doing.
I'm not sure why that fails, but I suppose you can't Dispose a brush you are not specifically creating a new instance of..?
I don't understand why it fails every single time here, but works fine with you? Maybe a recent update 'fixed' / 'destroyed' (I'm not sure which of the two ) this, seeing as this thread is half a year old?
The fix is just to not dispose your brush.
By the way, great control, looks very similar to the Visual Studio one.
In my opinion, a Designer class with Smart Tags would work wonders on this control... You could set the color more easily during design-time that way, as well as quickly including or excluding system colors / transparent with a checkbox.
If you want to implement the Smart Tags, do a search for them in the codebank, I made a 'tutorial' about them a while ago.
I get the Invalid Parameter exception too, on XP Media Center Edition 2005.
The Invalid Parameter exception occurs when you dispose a brush that is set to any of the default brushes in the Brushes enumeration, exactly what you are doing.
I'm not sure why that fails, but I suppose you can't Dispose a brush you are not specifically creating a new instance of..?
I don't understand why it fails every single time here, but works fine with you? Maybe a recent update 'fixed' / 'destroyed' (I'm not sure which of the two ) this, seeing as this thread is half a year old?
The fix is just to not dispose your brush.
Yea, I fixed that a few months ago, I just forgot to update the code in this thread, which is done.
Originally Posted by NickThissen
By the way, great control, looks very similar to the Visual Studio one.
In my opinion, a Designer class with Smart Tags would work wonders on this control... You could set the color more easily during design-time that way, as well as quickly including or excluding system colors / transparent with a checkbox.
If you want to implement the Smart Tags, do a search for them in the codebank, I made a 'tutorial' about them a while ago.
JuggaloBrotha, I get errors on ColorComboBox. It the IDE/Compiler doesn't like that I changed it to ComboBox1 and I get the same error. But when I use my code from earlier, I get no errors on ComboBox1. I tried all different versions of the code in the form_load even and none work
What's up you think?
Last edited by jumper77; Aug 9th, 2017 at 02:16 PM.
I actually know how to fix my code. It just wouldn't be very eloquent. I would just have to check to see if the colors where control colors and if so, do not add them to the combo box
JuggaloBrotha, I get errors on ColorComboBox. It the IDE/Compiler doesn't like that I changed it to ComboBox1 and I get the same error. But when I use my code from earlier, I get no errors on ComboBox1. I tried all different versions of the code in the form_load even and none work
What's up you think?
Granted I haven't used this control since a project in VS2010, I was able to open VS2015, drop the control into a project, add it to the form, and run it and it displayed the list of colors (without system colors, which it can do by changing a property) just fine:
Currently using VS 2015 Enterprise on Win10 Enterprise x64.
Hi Juggalo, didn't see your reply until just now. I download your project and it works, But I've already got code that works now and I think I will just use it. But thank you so much for giving me your project. It will help me learn some things.