Most controls can be extended by creating a class that inherits from the control and the System.Windows.Forms.Button is one of them. To create a custom button control you can simply inherit from the Button control and override or add new functionality. For this tutorial, I'll explain how to use GDI to design a custom button.
First you'll need to create a new class that inherits from System.Windows.Forms.Button. You then need to override the OnPaint method. Overriding this method will allow you to repaint over the button. Your code should look similar to listing 1.1 below.
Listing 1.1
The OnPaint method accepts a PaintEventArgs argument, which exposes the Graphics object that is used to paint the control. Using this Grapjics object, you can repaint the control as seen in listing 1.2 below.
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- class xButton : Button
- {
- protected override void OnPaint(PaintEventArgs pevent)
- {
- }
- }
Listing 1.2
The Graphics object exposes several methods for painting, one of which is the FillRectangle() method. This method takes the area to paint and the color to paint the area. In the above code a Rectangle instance specifies the area to paint, which is the full area of the button. If you run the code, you will notice, that the button caption does not appear. This is because you must draw the button text onto the button. This can be done using the Graphics objects DrawString() method as shown in listing 1.3 below.
- protected override void OnPaint(PaintEventArgs pevent)
- {
- Graphics g = pevent.Graphics;
- /** Area of Button */
- Rectangle area = new Rectangle(0, 0, this.Width, this.Height);
- /** Fill the area with a Blue solid color */
- g.FillRectangle(new SolidBrush(Color.Blue), area);
- }
Listing 1.3
When using the DrawString() method, you must specify where on the button you want to draw the button text as seen by the x and y variables. To position the text in the center of the button, you must first get the size of the text. This can be done using the MeasureString() method of the Graphics object. Once you have the text size, its easy to calculate the center text position. The code in listing 1.4 below shows how to align the text in the center of the button.
- int x = 0;
- int y = 0;
- g.DrawString(this.Text, new Font(this.Font, this.Font.Style), new SolidBrush(this.ForeColor), x, y);
Listing 1.4
You can add a hover event to the button so that the background color changes when the mouse moves over the button. To achieve this, you need to override the OnMouseEnter and the OnMouseLeave methods and store the mouse action in a variable. Listing 1.5 below shows a complete button class with mouse hover and click events.
- SizeF textSize = g.MeasureString(this.Text, this.Font);
- int x = (int)(area.Width - textSize.Width) / 2;
- int y = (int)(area.Height - textSize.Height) / 2;
Listing 1.5
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- class xButton : Button
- {
- bool _hoverState = false;
- bool _downState = false;
- public xButton()
- {
- this.BackColor = Color.Black;
- this.HoverBackgroundColor = Color.Black;
- this.ClickedBackgroundColor = Color.White;
- this.BackgroundGradientOffset = 0;
- }
- public Point TextPosition
- {
- set;
- get;
- }
- public Color ClickedBackgroundColor
- {
- set;
- get;
- }
- public Color HoverBackgroundColor
- {
- set;
- get;
- }
- public int BackgroundGradientOffset
- {
- set;
- get;
- }
- protected override void OnPaint(PaintEventArgs pevent)
- {
- Graphics g = pevent.Graphics;
- Rectangle area = new Rectangle(0, 0, this.Width, this.Height);
- g.DrawRectangle(new Pen(new SolidBrush(this.BackColor)), area);
- if (this._hoverState)
- {
- g.FillRectangle(new SolidBrush(ClickedBackgroundColor), area);
- g.DrawString(this.Text, new Font(this.Font, this.Font.Style), new SolidBrush(this.BackColor), this.TextPosition.X, this.TextPosition.Y);
- }
- else if (this._downState)
- {
- g.FillRectangle(new SolidBrush(Color.Black), area);
- g.DrawString(this.Text, new Font(this.Font, this.Font.Style), new SolidBrush(this.BackColor), this.TextPosition.X, this.TextPosition.Y);
- }
- else
- {
- int red = (this.BackColor.R > this.BackgroundGradientOffset) ? this.BackColor.R - this.BackgroundGradientOffset : 0;
- int green = (this.BackColor.G > this.BackgroundGradientOffset) ? this.BackColor.G - this.BackgroundGradientOffset : 0;
- int blue = (this.BackColor.B > this.BackgroundGradientOffset) ? this.BackColor.B - this.BackgroundGradientOffset : 0;
- Color gradientColor = Color.FromArgb(red, green, blue);
- LinearGradientBrush lgBrush = new LinearGradientBrush(area, this.BackColor, gradientColor, 1);
- gradientColor = Color.FromArgb(red, green, blue);
- g.FillRectangle(lgBrush, area);
- g.DrawString(this.Text, new Font(this.Font, this.Font.Style), new SolidBrush(this.ForeColor), this.TextPosition.X, this.TextPosition.Y);
- }
- }
- protected override void OnMouseEnter(EventArgs e)
- {
- _hoverState = true;
- base.OnMouseEnter(e);
- }
- protected override void OnMouseLeave(EventArgs e){
- _hoverState = false;
- base.OnMouseLeave(e);
- }
- protected override void OnMouseDown(MouseEventArgs e)
- {
- _downState = true;
- _hoverState = false;
- base.OnMouseDown(e);
- }
- protected override void OnMouseUp(MouseEventArgs e)
- {
- _downState = false;
- _hoverState = false;
- base.OnMouseUp(e);
- }
- }
No comments:
Post a Comment