Change the Look of a Button Using Skins
July 6th, 2007Download the Silverlight sample project
Download the Flash sample project
Introduction
By default, the controls provided with GOA WinForms for Silverlight and GOA WinForms for Flash have a Windows XP look and feel.
This QuickStart topic describes how to change the look of a button control using the skinning features.
Prerequisites:
If you are using GOA WinForms for Flash:
- Adobe Flash Player (version 9.0 recommended)
- Microsoft Visual Studio 2005.
- GOA WinForms for Flash (available from the NETiKA Technologies site)
If you are using GOA WinForms for Silverlight:
- Microsoft Silverlight 2.0 Beta 2
- Microsoft Visual Studio 2008
- Microsoft Silverlight Tools Beta 2 for Visual Studio 2008
- GOA WinForms for Silverlight (available from the NETiKA Technologies site)
Display four buttons on a form
In order to be able to see the skin changes we are going to make, we are first creating a form holding four buttons.
Start Visual Studio and create a new GOA Application project. Name your project SkinChange.
If you do not know how to create a new GOA project, please read the Create a "Hello World" Application with GOA WinForms for Silverlight or the Create a "Hello World" Application with GOA WinForms for Flash QuickStart on this site.
When the project has been created, a new form holding a button has also automatically been created. Start editing the form file (Form1.ccs or MyForm.cs)
At the beginning of the file, add 3 buttons fields:
private Button button2; private Button button3; private Button button4;In the InitializeComponent method of the form, add the code needed to create and display the 4 buttons on the form:
private void InitializeComponent() { this.button1 = new Button(); this.button2 = new Button(); this.button3 = new Button(); this.button4 = new Button(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point(50, 20); this.button1.Text = "button1"; this.button1.Height = 30; this.button1.Width = 70; // // button2 // this.button2.Location = new System.Drawing.Point(50, 60); this.button2.Text = "button2"; this.button2.Height = 30; this.button2.Width = 70; // // button3 // this.button3.Location = new System.Drawing.Point(50, 100); this.button3.Text = "button3"; this.button3.Height = 30; this.button3.Width = 70; // // button4 // this.button4.Location = new System.Drawing.Point(50, 140); this.button4.Text = "button4"; this.button4.Height = 30; this.button4.Width = 70; this.button4.Enabled = false; // // Form1 // this.Controls.Add(this.button1); this.Controls.Add(this.button2); this.Controls.Add(this.button3); this.Controls.Add(this.button4); this.Text = "Form1"; this.ResumeLayout(false); }Click Start on the Debug menu or press F5. A form displaying four standard buttons is displayed. The four buttons have a Windows XP look and feel
Create a new ButtonSkin
In GOA, the painting process of the controls is managed by their ControlSkins. Each control has its own ControlSkin which is located in the System.Windows.Forms.Skins.WinXP namespace.
The type of the default control skin for a button is System.Windows.Forms.Skins.WinXP.MyButtonSkin.
We are going to create a new control skin that will replace the default MyButtonSkin.
The new look will be very simple and have the following features:
- The button will be drawn as a light blue rectangle with a black border and with a black text.
- If the mouse is over the button, the border of the rectangle will become red.
- If the button has the focus, the background of the rectangle will become cyan.
- If the button is down, the background of the rectangle will become dark blue and the text will become white.
- If the button is disabled, the background of the rectangle will be gray and the text color will be dark gray.
Let's start creating the new ControlSkin.
- Create a new class file and name it ButtonSkinSample.
- Type the following code into the ButtonSkinSample file:
using System; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.Skins; namespace SkinChange { public class ButtonSkinSample : ButtonSkin { //textelement is used to display the text of the button TextElement textElement = null; public ButtonSkinSample(Button control) : base(control) { } public override void Dispose() { if (textElement != null) { textElement.Dispose(); textElement = null; } base.Dispose(); } public override void OnPaint(PaintEventArgs e) { Visual visual = this.Visual; //Clear the visual of the button before starting //the painting process visual.Clear(); visual.ClearStroke(); Button button = (Button)control; //Define the back color, the border color and the text color //according to the state of the button: // (clicked, disabled, focused...) Color borderColor = Color.Black; Color backColor = Color.LightBlue; Color textColor = Color.Black; if (this.control.Enabled) { if (this.MouseIsOver) borderColor = Color.Red; if (this.ButtonIsDown) { backColor = Color.DarkBlue; textColor = Color.White; } else if (this.control.Focused) backColor = Color.Cyan; } else { backColor = Color.Gray; textColor = Color.DarkGray; } //Draw the border and the background of the button visual.SetStroke(1, borderColor); visual.BeginSolidFill(backColor); visual.DrawRectangle(0, 0, this.control.Width, this.control.Height); //Display the text of the button if (textElement == null || textElement.IsDisposed) textElement = new TextElement(visual); textElement.X = 5; textElement.Y = 5; textElement.Width = control.Width - 10; textElement.Height = control.Height - 10; textElement.Alignment = button.TextAlign; textElement.Color = textColor; textElement.Text = control.Text; textElement.Font = control.Font; } } }
We have just created a new ControlSkin for the button control.
Applying the skin to the four buttons
There are several ways to apply the ButtonSkin. First, we will have a look on how to apply this skin on a single set of buttons.
In order to achieve this, we will need to override the CreateControlSkinInstance method of the button. This method is a virtual method of the control class. It returns the ControlSkin that must be used by the control. Each control overrides this method in order to return its own skin.
- Create a new class file and name it SampleButton.
- Type the following code into the SampleButton file:
using System; using System.Windows.Forms; using System.Windows.Forms.Skins; namespace SkinChange { public class SampleButton : Button { protected override ControlSkin CreateControlSkinInstance() { return new ButtonSkinSample(this); } } }
- Open the form file (Form1.ccs or MyForm.cs) and replace Button by SampleButton:
public class Form1 : System.Windows.Forms.Form { private SampleButton button1; private SampleButton button2; private SampleButton button3; private SampleButton button4; . . . private void InitializeComponent() { this.button1 = new SampleButton(); this.button2 = new SampleButton(); this.button3 = new SampleButton(); this.button4 = new SampleButton(); . . . } . . . }
Click Start on the Debug menu or press F5. The form is displayed. The four buttons are now displayed using the new ControlSkin
Replace the default skin
It is also possible to automatically apply the ButtonSkin that we have created to any button.
The Control class has a static DefaultSkin property. This property allows setting the default skins that will be used by all the controls of the application. The type of the property is System.Windows.Forms.Skins.Skin. Do not make confusion between Skin and ControlSkin. The Skin class allows specifying the ControlSkins that are used by the controls. By default, the CreateControlSkinInstance method of the Control class makes a call to a method of the Skin class to retrieve the ControlSkin it must use. For instance, the CreateControlSkinInstance method of the Button control calls the CreateButtonSkin method of its Skin object. By overriding, the CreateButtonSkin method of the Skin class you can force all the buttons to use a custom skin.
The default Skin used by all the controls is the WinXPSkin defined in the System.Windows.Forms.Skins.WinXP namespace.
We are going to override this skin in order to apply the ButtonSkinSample ControlSkin that we have created to any button of the application.
- Create a new class file and name it SampleSkin.
- Type the following code into the SampleSkin file:
using System; using System.Windows.Forms.Skins.WinXP; using System.Windows.Forms.Skins; using System.Windows.Forms; namespace SkinChange { public class SampleSkin: WinXPSkin { //You need to override the name property //on any custom skin you create public override string Name { get { return "SampleSkin"; } } public override ButtonSkin CreateButtonSkin(Button control) { return new ButtonSkinSample(control); } } }
- Open the form file (Form1.ccs or MyForm.cs) and replace back SampleButton by Button.
- Add the following line at the beginning of the InitializeComponent method:
Click Start on the Debug menu or press F5. The form holding the four buttons is displayed. The four buttons are displayed using the new ControlSkin.
Note: A third way to apply a skin is to use the Skin property of the control. In that case, rather than applying a skin to all the controls of the application, you simply apply it to one control by setting a value in its Skin property.