Click here to Skip to main content
13,446,392 members (39,328 online)
Click here to Skip to main content
Add your own
alternative version


32 bookmarked
Posted 10 Jan 2003

A simple XP/VS.NET style button control

, 10 Jan 2003
Rate this:
Please Sign up or sign in to vote.
Why another button control? Because I searched the net for a control that would mimic the XP/VS.NET style buttons, but I couldn't find a decent one. I think this button has all needed functionality: cool style, shortcut keys, icons, alignment, ...

Sample Image - top.jpg


Recently I was searching for a control that would look like the new XP/VS.NET style button control. The button control needed to have the features described in this article. But I couldn't find a free control that provided all these features, so I created one myself. This is my first version, it provides basic functionality that you can already use. But there will soon be more features added.

Feature 1: Basic button functionality

Ah, this is an easy one most people would think. Ofcourse there must be a simple OnClick event:

Public Shadows Event Click(ByVal sender As Object, ByVal e As EventArgs)

But if you look at the standard functionality of the Button control provided in the .NET framework, you will see that there are some more things needed for the basic button functionality. The first one is that you can set the Text property to '&Save', and when you press the keys alt+S, the Click event of the button would be triggered. I've searched a long time after this one, but with some help in a few newsgroups I managed to add this functionality by overriding the ProcessMnenomic function:

Protected Overrides Function ProcessMnemonic(ByVal charCode As Char) _
                                                            As Boolean
    Dim ampPosition As Integer = _text.IndexOf("&")
    Dim charToCheck As Char
    If ampPosition > -1 And ampPosition < _text.Length Then
        charToCheck = _text.Chars(ampPosition + 1)

        If Char.ToLower(charToCheck) = Char.ToLower(charCode) Then
            Return True
        End If
    End If
    Return False
End Function

When you place a Button control on a Form, you can specify that, that button is the AcceptButton or CancelButton. To accomplish this the IButtonControl interface must be implemented:

<System.ComponentModel.DefaultValue(GetType(DialogResult), Nothing)> _
    Public Overridable Overloads Property DialogResult() As DialogResult _
    Implements IButtonControl.DialogResult
        Return _dialogResult
    End Get
    Set(ByVal Value As DialogResult)
        _dialogResult = Value
    End Set
End Property

Public Overridable Overloads Sub NotifyDefault(ByVal value As Boolean) _
                            Implements IButtonControl.NotifyDefault
    'Not needed
End Sub

Public Overridable Overloads Sub PerformClick() Implements _
    clickHandler(Me, Nothing)
End Sub

This is the basic functionality needed for the button control.

Feature 2: XP style border and backcolor

In Office XP or VS.NET when you move your mouse over a button, the border of the button is painted blue and the backcolor is blue also. This is pretty easy to code:

Private Sub NewFlatButton_Paint(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.PaintEventArgs)_
    Handles MyBase.Paint
    If Me.blueBorder Then
        e.Graphics.DrawRectangle(New Pen(_bordercolorFocus), _
                            0, 0, Me.Width - 1, Me.Height - 1)
        e.Graphics.DrawRectangle(New Pen(_bordercolor), _
                        0, 0, Me.Width - 1, Me.Height - 1)
    End If
End Sub

Feature 3: XP style images

This is the most fun part! When you look really close at an XP style button you will notice that there are some very neat effects for the images. In a normal state (no mouse over the button), a button displays a picture with slightly brighter colors than normal. When you move the mouse over the button, the pictures recieve shadow and will be displayed in normal colors (darker than before). When you press the button, the picture loses its shadow, but is still displayed in darker (normal) colors. The control only needs 1 picture, and generates the other 2 needed by code.

Here is an example of a picture in the 3 possible states:

Normal, with smooth, brighter colors.

Raised, with darker colors and shadow.

Pressed, with darker colors, no shadow.

First I needed a function to calculate the color shifts to the brighter colors (I found the formula on

Private Function TransformColor(ByVal x As Long) As Long
    Return 76 - Int((x + 32) / 64) * 19 + x
End Function

The function to create the brighter image is:

Private Function GetSmoothImage(ByVal image As Image) As Image
    Dim bmp As New Bitmap(image)
    Dim x As Integer, y As Integer
    For x = 0 To bmp.Width - 1
        For y = 0 To bmp.Height - 1
            Dim oldColor As Color = bmp.GetPixel(x, y)
            If Not oldColor.Equals(Color.FromArgb(0, 0, 0, 0)) Then
                Dim newColor As Color = _
                            Color.FromArgb(TransformColor(oldColor.R), _
                            TransformColor(oldColor.G), _
                bmp.SetPixel(x, y, newColor)
            End If
    Return bmp
End Function

To generate the image for the button when the mouse is over it, first the image is converted to black and white (in a gray color). Then the original image is painted over it, but 2 pixels up and to the right. Like this you get a nice dropdown shadow effect:

Private Function GetRaisedImage(ByVal image As Image) As Image
    Dim bmp As New Bitmap(image)
    Dim newBmp As New Bitmap(bmp.Width + 2, bmp.Height + 2)
    Dim x As Integer, y As Integer
    For x = 0 To bmp.Width - 1
        For y = 0 To bmp.Height - 1
            Dim oldcolor As Color = bmp.GetPixel(x, y)
            If oldcolor.Equals(Color.FromArgb(0, 0, 0, 0)) Then
                newBmp.SetPixel(x + 2, y + 2, Color.Transparent)
                newBmp.SetPixel(x + 2, y + 2, Color.Gray)
            End If

    Dim g As Graphics = Graphics.FromImage(newBmp)
    g.DrawImage(image, 0, 0)
    Return newBmp
End Function

Finally, the image needed when the button is pressed, is equal to the original image:

Private Function GetDownImage(ByVal image As Image) As Image
    Return _image
End Function

Other features

Some other features that are built into this control, but which I will not explain here are: text alignment, different border colors and image margin. You can find the code in the source project.

Features for the future

You can use this control already, because it has all the needed functionality. But there are some nice-to-have features that will be implemented somewhere in the (near?) future: image alignment, .ICO file type support, ... If you have other needs or ideas, please let them know!


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Jan Tielens
Web Developer U2U
Saudi Arabia Saudi Arabia
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralThx! Pin
tidoy3-Dec-04 3:15
membertidoy3-Dec-04 3:15 
GeneralCrystal report Pin
Anonymous27-Sep-04 17:30
sussAnonymous27-Sep-04 17:30 
GeneralStupid Pin
viper@excite.com12-Mar-04 8:24
memberviper@excite.com12-Mar-04 8:24 
QuestionIs anyone still updating this control? Pin
eudora6-Mar-04 4:47
membereudora6-Mar-04 4:47 
I think there is lots of bugs like the label etc.. can anyone help out on this control?Cry | :((
QuestionTooltip doesn't show? Pin
J_Rulz31-Jan-04 14:21
memberJ_Rulz31-Jan-04 14:21 
GeneralMouseEvents screwup Pin
gwapo16-Jan-04 1:30
membergwapo16-Jan-04 1:30 
GeneralNice control, just one more suggestion Pin
gwapo11-Jan-04 19:24
membergwapo11-Jan-04 19:24 
GeneralDoesn't Build in VS2003 Pin
DWRoelands29-Dec-03 7:02
memberDWRoelands29-Dec-03 7:02 
GeneralRe: Doesn't Build in VS2003 Pin
videocorner15-Apr-04 7:35
membervideocorner15-Apr-04 7:35 
GeneralRe: Doesn't Build in VS2003 Pin
Asad Naeem7-Jul-04 0:07
memberAsad Naeem7-Jul-04 0:07 
GeneralFires Click Event even on Right Click... Pin
myemptyfilled12-Oct-03 17:29
membermyemptyfilled12-Oct-03 17:29 
QuestionRound corners? Pin
Anonymous25-Sep-03 9:15
sussAnonymous25-Sep-03 9:15 
AnswerRe: Round corners? Pin
JInsane29-Sep-03 20:24
memberJInsane29-Sep-03 20:24 
AnswerRe: Round corners? Pin
praj2228-Feb-04 1:30
memberpraj2228-Feb-04 1:30 
GeneralHandling Key Events Pin
Darryl Buckby28-Aug-03 23:03
memberDarryl Buckby28-Aug-03 23:03 
GeneralMnenonic Pin
marcootilli26-Aug-03 23:28
membermarcootilli26-Aug-03 23:28 
GeneralNavigation Button Pin
nelson_vpf6-Jun-03 8:45
membernelson_vpf6-Jun-03 8:45 
Generalproblem Pin
superlg8-May-03 16:35
membersuperlg8-May-03 16:35 
Generalwhy not 3D style Pin
hustcaozy6-Apr-03 18:03
memberhustcaozy6-Apr-03 18:03 
GeneralRe: why not 3D style Pin
kh30qs9-Jun-03 4:05
memberkh30qs9-Jun-03 4:05 
GeneralRe: why not 3D style Pin
babugmin11-Jun-03 20:09
memberbabugmin11-Jun-03 20:09 
QuestionBug? Pin
OJO15-Jan-03 7:02
memberOJO15-Jan-03 7:02 
AnswerRe: Bug? Pin
Jan Tielens16-Jan-03 3:36
memberJan Tielens16-Jan-03 3:36 
GeneralProject added for .NET Framework 1.0 (VS 2002) Pin
Jan Tielens13-Jan-03 5:28
memberJan Tielens13-Jan-03 5:28 
GeneralDoesn't work Pin
Patrick Lujan12-Jan-03 15:15
memberPatrick Lujan12-Jan-03 15:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01-2016 | 2.8.180314.2 | Last Updated 11 Jan 2003
Article Copyright 2003 by Jan Tielens
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid