Click here to Skip to main content
12,631,123 members (30,670 online)
Click here to Skip to main content
Add your own
alternative version


220 bookmarked

XP-Style Button

, 24 Sep 2003
Rate this:
Please Sign up or sign in to vote.
.NET button that supports images and XP style on Windows XP and other versions of Windows.

Sample Image - XP-Style_Button.jpg


XP-Style Button provides the look and feel of a button with any of of the three built-in color schemes of Windows XP and will also work with earlier versions of Windows, or using a color scheme if you use Windows XP. You simply don't have to worry about how the button will look like on different versions of Windows - it will always look the same.


  • Resizing of the button doesn't work on appearance.
  • Button supports Image and Text property, which are optional.
  • Possibility to add a button to a form and set properties at the design and at the run time.
  • Tab order, navigating by buttons with keys <Tab>, <Up>, <Down>, <Left>, <Right>. If button has an input focus, <Return> and <Space> work as a left-button mouse click.
  • Access keys - possibility to trigger the click event of control by pressing the ALT key in combination with predefined key.
  • Accept button (button which is clicked when the user presses ENTER key if no other button or any other control that captures the ENTER key has focus) or Cancel button (button clicked when the user presses the ESC key) on the form.
  • Tool tip allows to set a hint with one line of code.
  • With DefaultScheme property set to false, the button always has the Windows XP color scheme that you chose, no matter what version of Windows or current Windows XP visual style.
  • On one form you may have buttons with different color schemes :)

Public properties

Scheme Allows you to choose one of the three Windows XP color schemes, for applications running under earlier versions of Windows and Windows XP. Setting DefaultScheme property to false allows you to show buttons with any of the three visual styles--Blue, Olive Green and Silver -- on one form. The default color scheme is Blue.
DefaultScheme If true, uses the default Windows XP color scheme (applies for Windows XP only, ignored for earlier versions of Windows).
DialogResult Gets or sets a value that is returned to the parent form when the button is clicked, if the parent form is displayed through the ShowDialog method.
Image Gets or sets the button's bitmap image.
Text Gets or sets the button's text.
TextColor Gets or sets a color of text.
Hint Gets or sets the ToolTip string. When setting the ToolTip string, removes string currently associated with the control.

Visual Design

  1. Setting the control region

    Everybody who used Windows XP has very probably noticed that buttons have rounded corners. The graphic shape of the button looks like this:

    So, we'll create such a region (the interior of a graphics shape) for our button.

    int X = this.Width; 
    int Y = this.Height;  
    Point[] points = {    new Point(1, 0), 
                          new Point(X-1, 0), 
                          new Point(X-1, 1), 
                          new Point(X, 1), 
                          new Point(X, Y-1), 
                          new Point(X-1, Y-1), 
                          new Point(X-1, Y), 
                          new Point(1, Y), 
                          new Point(1, Y-1), 
                          new Point(0, Y-1), 
                          new Point(0, 1), 
                          new Point(1, 1)}    
    GraphicsPath path = new GraphicsPath();
    this.Region = new Region(path);

    As you have probably guessed, the region is critical for drawing irregularly shaped controls.

  2. Tracking the mouse movement

    To accomplish a button's visual interaction on mouse movement, we'll override the OnMouseEnter, OnMouseLeave, OnMouseDown, OnMouseUp methods in order to paint the button differently, depending on button state.

    Bounds of control:

    private Rectangle bounds;
    this.bounds = new Rectangle(0, 0, this.Width, this.Height);

    Possible states:

    public enum States 


    protected override void OnMouseEnter
                (System.Windows.Forms.MouseEventArgs e)
        state = States.MouseOver;  
    protected override void OnMouseLeave(System.EventArgs e)
        state = States.Normal;
    protected override void OnMouseDown
               (System.Windows.Forms.MouseEventArgs e) 
        // do nothing if pressed not the left button of mouse
        if ((e.Button & MouseButtons.Left) != MouseButtons.Left) return;
        if (bounds.Contains(e.X, e.Y)) 
            state = States.Pushed; 
            // button receives an imput focus
        else state = States.Normal;
    protected override void OnMouseUp
              (System.Windows.Forms.MouseEventArgs e) 
        if ((e.Button & MouseButtons.Left) == MouseButtons.Left) 
            state = States.Normal;
  3. Default button

    What we are missing now is to trace and paint button in normal state, but when it is a default button (blue rectangle inside the borders, for Blue and Silver color schemes and green rectangle inside the borders, for Olive Green color scheme). We'll declare a boolean variable isDefault, to know whenever the button is default. NotifyDefault method is called by a parent form to make a control the default button:

    public void NotifyDefault(bool value)
        this.isDefault = value;

    Now, when we paint the button's Normal state, we should check if it's active or not and perform painting depending on isDefault.

  4. Filling button with a LinearGradientBrush

    When it seems we've traced all possible button states, we can start to paint the control. Buttons in Windows XP are filled with linear gradient color. GDI+ offers two kinds of gradient brushes: LinearGradientBrush and PathGradientBrush. We need the first one. When creating a LinearGradientBrush we should:

    • point to its location (3, 3)
    • size (this.Width-6, this.Height-5) of a rectangular region for the gradient (notice, that you don't have to paint the whole gradient region)
    • the starting color for the gradient
    • the ending color for the gradient
    • the angle (in degrees, clockwise from the x-axis) that defines the orientation of gradient (we need vertical gradient, so we use 90.0f)
    silverBrush07 = new LinearGradientBrush(new Rectangle(3, 3, X-6, Y-7), 
         Color.FromArgb(253, 253, 253), 
         Color.FromArgb(201, 200, 220), 90.0f);

    But the Silver color scheme is different from the Blue and Olive Green: buttons have more "volume". To accomplish this effect, we'll adjust the way a color varies from one edge of a gradient to the other, setting the Blend property of LinearGradientBrush object.

    // color is much more intensive in the bottom part of the button
    // first 32 % of height we'll fill with
    // intencity 0.8 % from starting color:
    float[] relativeIntensities = {0.0f, 0.008f, 1.0f}; 
    float[] relativePositions = {0.0f, 0.32f, 1.0f};
    // create a Blend object and assign it to silverBrush07
    Blend blend = new Blend();
    blend.Factors = relativeIntensities;
    blend.Positions = relativePositions; 
    silverBrush07.Blend = blend; 
    // fill the nessecary shape:
    e.Graphics.FillRectangle(silverBrush07, 3, 4, 
                       this.Width-6, this.Height-8);  

    After drawing border lines and corners the result is:

Adding button to a Form

When the component is ready, we can add it to a form (don't forget to include PinkieControls namespace. The process is very simple, the most important is to not forget to set the Scheme property.

using System.Resources;  
using System.Reflection;  
using PinkieControls;  

private PinkieControls.ButtonXP buttonXP3;  
static ResourceManager rm; 
public Form1() 
    rm = new ResourceManager("TestApp.Images", 
    // If to add lines below in InitializeComponent()
    // we'll see the button at the design time
    // (doing so, don't forget to set _Image
    // and Image properties in null
    this.buttonXP3 = new PinkieControls.ButtonXP(); 
    this.buttonXP3._Image = GetImage("_Save");  
    this.buttonXP3.Image = GetImage("Save2");  
    this.buttonXP3.Text = @"Save";  
    this.buttonXP3.Location = new 
            System.Drawing.Point(152, 144);  
    this.buttonXP3.Name = "buttonXP3";  
    this.buttonXP3.Scheme = 
    this.buttonXP3.Size = new System.Drawing.Size(112, 26);  
    this.buttonXP3.TabIndex = 3;  
    this.buttonXP3.Click += new 
private void buttonXP3Click(object sender, System.EventArgs e) 
    MessageBox.Show("Hello, World :)")   

Setting default color scheme for Windows XP

If we'd like a button painted in current Windows XP color scheme, it's enough only to set the boolean property DefaultScheme, to true (by default it's false). For example,

myButton.Scheme = PinkieControls.ButtonXP.Schemes.Silver;   
myButton.DefaultScheme = true; 

In this case, earlier versions of Windows will have silver color for the button. For Windows XP (with themes on) the button will have current color scheme.

Creating access keys

User can trigger the click event of control by pressing the ALT key in combination with predefined access key. Normally we add an ampersand (&) before the letter we intend to make an access key. ProcessMnemonic method is called to give a control the opportunity to process a mnemonic character:

protected override bool ProcessMnemonic(char charCode)
    // determine if the given character matches
    // a mnemonic in the control's text
    if (Control.IsMnemonic(charCode, base.Text))
    return true;
    return base.ProcessMnemonic(charCode);

Now, if we'll set the Text property to a string that includes an ampersand before the letter, that is going to be a shortcut:

buttonExit.Text = "E&xit";

We can run the command associated with the buttonExit by pressing ALT + X. It will close the form.

How to delete effect of slow painting while form is loading.

Derive your form from PinkieControls.FormEx. The form contains timer which is used to load the form with the fade effect. Interval of timer is set by default in so little value that our eyes don't notice that form fades in, while loading. You can change FadeTime property.

Thanks all for the comments and critique. New suggestions and ideas are welcome. Enjoy ;o)


  • 28.05.2003:
    • Fixed bug with DefaultScheme property
    • Access key added
  • 04.06.2003
    • Access key implementation by Wes Haggard (AKA puzzlehacker)
    • Implemented IButtonControl interface by Wes Haggard (AKA puzzlehacker)
    • Painting for the focused button (the focus rectangle around the button) by Wes Haggard (AKA puzzlehacker)
    • Pens and brushes are wrapped in separate class
    • Source code and demo project downloads updated
  • 08.08.2003:
    • Deleted effect of slow painting of button while loading form at first time (white rectangle on the place of button).
    • Changed the name of namespace from WiB.Pinkie.Controls to PinkieControls.
    • Added TextColor and Hint properties.
    • All implementation of button control is pulled out in a separate ButtonBase class which allows easily to reuse the code and implement your own stylish button.
    • Created round button.


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

Valeria Bogdevich
Software Developer
Portugal Portugal
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralRe: Exceptions when app starts Pin
WiB17-Aug-05 3:37
memberWiB17-Aug-05 3:37 
GeneralPlease explain the purpose of the winAPI Pin
rthillusa31-Jul-05 15:08
memberrthillusa31-Jul-05 15:08 
GeneralRe: Please explain the purpose of the winAPI Pin
WiB17-Aug-05 4:04
memberWiB17-Aug-05 4:04 
GeneralNew version Pin
akorolev1016-Jul-05 2:15
memberakorolev1016-Jul-05 2:15 
GeneralRe: New version Pin
WiB27-Jul-05 10:45
memberWiB27-Jul-05 10:45 
GeneralWarning message Pin
akorolev1013-Jul-05 23:06
memberakorolev1013-Jul-05 23:06 
GeneralNew version Pin
akorolev109-Jul-05 5:08
memberakorolev109-Jul-05 5:08 
GeneralPlease review your source code. Pin
j-soft1-Jun-05 3:15
memberj-soft1-Jun-05 3:15 
GeneralSuggested improvement... Pin
willcoxson9-May-05 8:20
memberwillcoxson9-May-05 8:20 
GeneralThank You for this greate xp-button style Pin
A.L1-Mar-05 23:18
memberA.L1-Mar-05 23:18 
GeneralRe: Thank You for this greate xp-button style Pin
WiB3-Mar-05 3:54
memberWiB3-Mar-05 3:54 
GeneralRadio Buttons and Checkboxes Pin
rlandfair27-Jan-05 10:56
memberrlandfair27-Jan-05 10:56 
GeneralPlease answer :Warning on XP Buttons Pin
M.Karimipour26-Jan-05 22:42
memberM.Karimipour26-Jan-05 22:42 
GeneralRe: Please answer :Warning on XP Buttons Pin
narayanvijay23-Nov-05 18:55
membernarayanvijay23-Nov-05 18:55 
GeneralXP style Button Pin
ananthboy25-Nov-04 8:46
memberananthboy25-Nov-04 8:46 
GeneralVb net version Pin
is_vlb5027-Oct-04 7:10
memberis_vlb5027-Oct-04 7:10 
GeneralRe: Vb net version Pin
WiB29-Oct-04 6:03
memberWiB29-Oct-04 6:03 
GeneralRe: Vb net version Pin
LongHC2-May-05 11:13
memberLongHC2-May-05 11:13 
GeneralButtonXP.Image - won't work directly Pin
BlinZaparaSEtimiImenami20-Oct-04 0:11
memberBlinZaparaSEtimiImenami20-Oct-04 0:11 
GeneralDefaultStyle - dont work in designer Pin
BlinZaparaSEtimiImenami19-Oct-04 23:59
memberBlinZaparaSEtimiImenami19-Oct-04 23:59 
GeneralRe: DefaultStyle - dont work in designer Pin
WiB29-Oct-04 6:59
memberWiB29-Oct-04 6:59 
Generalrounding the form border Pin
aqsmohsin20-Sep-04 9:47
memberaqsmohsin20-Sep-04 9:47 
GeneralRe: rounding the form border Pin
WiB29-Oct-04 7:03
memberWiB29-Oct-04 7:03 
GeneralImages not transparent Pin
Juicy26-Aug-04 23:29
memberJuicy26-Aug-04 23:29 
GeneralControlPaint.DrawBorder && e.Graphics.FillRegion Pin
bmyatt5-Jul-04 18:58
memberbmyatt5-Jul-04 18:58 
GeneralRe: ControlPaint.DrawBorder &amp;&amp; e.Graphics.FillRegion Pin
WiB10-Jul-04 12:28
memberWiB10-Jul-04 12:28 
Generallatest Version with changes??. Pin
CompoSID4-Jul-04 4:13
memberCompoSID4-Jul-04 4:13 
GeneralUsfull XP-Style Button! Pin
Nie.Yong14-May-04 5:51
memberNie.Yong14-May-04 5:51 
GeneralButton appears unpressed when moving one pixel Pin
Dominik Reichl11-Apr-04 10:41
memberDominik Reichl11-Apr-04 10:41 
GeneralRe: Button appears unpressed ... (Bugfix) Pin
Dominik Reichl13-Apr-04 8:06
memberDominik Reichl13-Apr-04 8:06 
GeneralButton doesn't appear pressed Pin
GabeG5-Apr-04 13:31
memberGabeG5-Apr-04 13:31 
QuestionSetting DefaultScheme to true is very slow?? Pin
Michael Bemmerl23-Mar-04 11:16
memberMichael Bemmerl23-Mar-04 11:16 
AnswerRe: Setting DefaultScheme to true is very slow?? Pin
WiB24-Mar-04 0:22
memberWiB24-Mar-04 0:22 
GeneralRe: Setting DefaultScheme to true is very slow?? Pin
Michael Bemmerl24-Mar-04 12:19
memberMichael Bemmerl24-Mar-04 12:19 
GeneralRe: Setting DefaultScheme to true is very slow?? Pin
Michael Bemmerl24-Mar-04 12:29
memberMichael Bemmerl24-Mar-04 12:29 
GeneralRe: Setting DefaultScheme to true is very slow?? Pin
WiB25-Mar-04 3:00
memberWiB25-Mar-04 3:00 
GeneralButtonBase in the WebForms Pin
Andrzej.Budny24-Feb-04 7:10
memberAndrzej.Budny24-Feb-04 7:10 
GeneralRe: ButtonBase in the WebForms Pin
WiB24-Mar-04 0:24
memberWiB24-Mar-04 0:24 
GeneralButtonBase in ToolBox Pin
diflu20-Jan-04 23:59
memberdiflu20-Jan-04 23:59 
GeneralRe: ButtonBase in ToolBox Pin
WiB11-Feb-04 5:48
memberWiB11-Feb-04 5:48 
GeneralRe: ButtonBase in ToolBox Pin
diflu15-Feb-04 23:45
memberdiflu15-Feb-04 23:45 
QuestionWhat license is there for this project? Pin
Gmonkey12-Jan-04 9:53
memberGmonkey12-Jan-04 9:53 
AnswerRe: What license is there for this project? Pin
WiB14-Jan-04 3:02
memberWiB14-Jan-04 3:02 
AnswerRe: What license is there for this project? Pin
WiB16-Jul-04 15:26
memberWiB16-Jul-04 15:26 
QuestionHow do I center the text? Pin
sinnen8-Jan-04 11:27
membersinnen8-Jan-04 11:27 
AnswerRe: How do I center the text? Pin
WiB9-Jan-04 6:11
memberWiB9-Jan-04 6:11 
GeneralRe: How do I center the text? Pin
sinnen10-Jan-04 11:14
membersinnen10-Jan-04 11:14 
GeneralRe: How do I center the text? Pin
evn13-Feb-05 18:02
memberevn13-Feb-05 18:02 
QuestionHow to enlarge the rounded corners? Pin
jienao28-Oct-03 20:03
memberjienao28-Oct-03 20:03 
AnswerRe: How to enlarge the rounded corners? Pin
WiB29-Oct-03 0:59
memberWiB29-Oct-03 0:59 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161205.3 | Last Updated 25 Sep 2003
Article Copyright 2003 by Valeria Bogdevich
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid