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
|
Office XP |
Office 2003 |
normal |
|
|
focused |
|
|
disabled |
|
|
dropeddown |
|
|
Enum states
normal
focused
dropeddown
disabled
End Enum
Dim state As states = states.normal
Function UpdateState()
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
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
If Me.DropDownStyle = _
ComboBoxStyle.Simple Then Exit Sub
g = Me.CreateGraphics
If Me.Enabled Then
g.Clear(Color.White)
Else
g.Clear(Color.FromName("control"))
End If
DrawButton(g)
DrawArrow(g)
DrawBorder(g)
DrawText(g)
Case 7, 8, &H7, &H8, &H200, &H2A3
UpdateState()
End Select
End Sub
To change the style (XP/2003), I've added a Public
property:
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.