Flat ComboBox with MS Office XP/2003 style support






4.79/5 (40 votes)
An article on creating a flat combobox using VB.NET.
- Download control source files - 2.63 Kb
- Download demo project (VS.NET 2003 - .NET 1.1) - 255 Kb
- Download demo project (VS.NET 2005 - .NET 2.0) - 480 Kb
Introduction
First of all, on the Internet, a lot of examples of flat combo boxes can be found. I tried to make a very simple one with a lot of functionality. On the screenshot above, you can see the functions that I have integrated: support for big fonts (the arrow will be centered), RTL (right to left) support, support for two dropdown styles (simple
is not supported yet), and of course the two styles.
The different states
|
| |
normal |
|
|
focused |
|
|
disabled |
|
|
dropeddown |
|
|
'Enum with all the possible states
Enum states
normal
focused
dropeddown
disabled
End Enum
'Variable to save the current state
Dim state As states = states.normal
Function UpdateState()
'save the current state
Dim temp As states = state
'
If Me.Enabled Then
If Me.DroppedDown Then
Me.state = states.dropeddown
Else
If ClientRectangle.Contains(_
PointToClient(Me.MousePosition)) Then
Me.state = states.focused
ElseIf Me.Focused Then
Me.state = states.focused
Else
Me.state = states.normal
End If
End If
Else
Me.state = states.disabled
End If
'only redraw if the state has changed
If state <> temp Then
Me.Invalidate()
End If
End Function
Using the code
FlatComboBox
is a UserControl
based on Windows.Forms.ComboBox
:
Imports System.Drawing.Drawing2D
Public Class FlatComboBox
Inherits System.Windows.Forms.ComboBox
'...
End Class
Reacting on events (mousemove
etc.) is done by overriding WndProc
:
Protected Overrides Sub WndProc(ByRef m As _
System.Windows.Forms.Message)
MyBase.WndProc(m)
Select Case m.Msg
Case &HF
'WM_PAINT
'"simple" is not currently supported
If Me.DropDownStyle = _
ComboBoxStyle.Simple Then Exit Sub
'==========START DRAWING===========
g = Me.CreateGraphics
'clear everything
If Me.Enabled Then
g.Clear(Color.White)
Else
g.Clear(Color.FromName("control"))
End If
'call the drawing functions
DrawButton(g)
DrawArrow(g)
DrawBorder(g)
DrawText(g)
'===========STOP DRAWING============
Case 7, 8, &H7, &H8, &H200, &H2A3
'CMB_DROPDOWN, CMB_CLOSEUP, WM_SETFOCUS,
'WM_KILLFOCUS, WM_MOUSEMOVE,
'WM_MOUSELEAVE (if you move the mouse fast over
'the combobox, mouseleave doesn't always react)
UpdateState()
End Select
End Sub
To change the style (XP/2003), I've added a Public
property:
'Property to let the user change the style
Public Property FlatComboStyle() As styles
Get
Return style
End Get
Set(ByVal Value As styles)
style = Value
End Set
End Property
Points of interest
In the combo box, there are two parts (the control itself and a kind of textbox). If the DropDownStyle
is set to DropDownList
, I need to draw the text manually because then there is no textbox. Because the event MouseLeave
doesn't always react, a timer refreshes the control every 20 ms. Just have a look at the code and you will see how easy it is!
Thanks to
Update
- Bug fix: Timer will be disabled while disposing! (See reactions below for more information.)
- First revision: Some big and small bugs are now fixed! (See reactions below for more information.)
- Second revision: '
Function
' replaced by 'Private Sub
' and others, and added a VB 2005 (.NET 2.0) version of the demo.