传统的VC#中的按钮不好看,如果要把软件界面做得漂亮一点。Vista风格的按钮或水晶风格的按钮的应用会大大提高我们的程序的美观程度。
如果要实现一个自定义的按钮,其实就是继承一个Button类,然后自己做一些扩展,实现出自己想要的效果。
以下代码实现了一个Vista风格的按钮,按钮是透明渐变的,按钮上还可以显示一个图片,效果如下:

代码如下,你可以创建一个控件库项目,最后生成一个.dll文件,在其他的项目中就可以引用并使用这种按钮了。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using PushButtonState = System.Windows.Forms.VisualStyles.PushButtonState;
namespace Glass
{
/// <summary>
/// Represents a glass button control.
/// </summary>
[ToolboxBitmap(typeof(GlassButton)), ToolboxItem(true), ToolboxItemFilter("System.Windows.Forms"), Description("Raises an event when the user clicks it.")]
public partial class GlassButton : Button
{
#region " Constructors "
/// <summary>
/// Initializes a new instance of the <see cref="Glass.GlassButton" /> class.
/// </summary>
public GlassButton()
{
InitializeComponent();
timer.Interval = animationLength / framesCount;
base.BackColor = Color.Transparent;
BackColor = Color.Black;
ForeColor = Color.White;
OuterBorderColor = Color.White;
InnerBorderColor = Color.Black;
ShineColor = Color.White;
GlowColor = Color.FromArgb(-7488001);//unchecked((int)(0xFF8DBDFF)));
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
SetStyle(ControlStyles.Opaque, false);
}
#endregion
#region " Fields and Properties "
private Color backColor;
/// <summary>
/// Gets or sets the background color of the control.
/// </summary>
/// <returns>A <see cref="T:System.Drawing.Color" /> value representing the background color.</returns>
[DefaultValue(typeof(Color), "Black")]
public virtual new Color BackColor
{
get { return backColor; }
set
{
if (!backColor.Equals(value))
{
backColor = value;
UseVisualStyleBackColor = false;
CreateFrames();
OnBackColorChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets or sets the foreground color of the control.
/// </summary>
/// <returns>The foreground <see cref="T:System.Drawing.Color" /> of the control.</returns>
[DefaultValue(typeof(Color), "White")]
public virtual new Color ForeColor
{
get { return base.ForeColor; }
set
{
base.ForeColor = value;
}
}
private Color innerBorderColor;
/// <summary>
/// Gets or sets the inner border color of the control.
/// </summary>
/// <returns>A <see cref="T:System.Drawing.Color" /> value representing the color of the inner border.</returns>
[DefaultValue(typeof(Color), "Black"), Category("Appearance"), Description("The inner border color of the control.")]
public virtual Color InnerBorderColor
{
get { return innerBorderColor; }
set
{
if (innerBorderColor != value)
{
innerBorderColor = value;
CreateFrames();
if (IsHandleCreated)
{
Invalidate();
}
OnInnerBorderColorChanged(EventArgs.Empty);
}
}
}
private Color outerBorderColor;
/// <summary>
/// Gets or sets the outer border color of the control.
/// </summary>
/// <returns>A <see cref="T:System.Drawing.Color" /> value representing the color of the outer border.</returns>
[DefaultValue(typeof(Color), "White"), Category("Appearance"), Description("The outer border color of the control.")]
public virtual Color OuterBorderColor
{
get { return outerBorderColor; }
set
{
if (outerBorderColor != value)
{
outerBorderColor = value;
CreateFrames();
if (IsHandleCreated)
{
Invalidate();
}
OnOuterBorderColorChanged(EventArgs.Empty);
}
}
}
private Color shineColor;
/// <summary>
/// Gets or sets the shine color of the control.
/// </summary>
/// <returns>A <see cref="T:System.Drawing.Color" /> value representing the shine color.</returns>
[DefaultValue(typeof(Color), "White"), Category("Appearance"), Description("The shine color of the control.")]
public virtual Color ShineColor
{
get { return shineColor; }
set
{
if (shineColor != value)
{
shineColor = value;
CreateFrames();
if (IsHandleCreated)
{
Invalidate();
}
OnShineColorChanged(EventArgs.Empty);
}
}
}
private Color glowColor;
/// <summary>
/// Gets or sets the glow color of the control.
/// </summary>
/// <returns>A <see cref="T:System.Drawing.Color" /> value representing the glow color.</returns>
[DefaultValue(typeof(Color), "255,141,189,255"), Category("Appearance"), Description("The glow color of the control.")]
public virtual Color GlowColor
{
get { return glowColor; }
set
{
if (glowColor != value)
{
glowColor = value;
CreateFrames();
if (IsHandleCreated)
{
Invalidate();
}
OnGlowColorChanged(EventArgs.Empty);
}
}
}
private bool isHovered;
private bool isFocused;
private bool isFocusedByKey;
private bool isKeyDown;
private bool isMouseDown;
private bool isPressed { get { return isKeyDown || (isMouseDown && isHovered); } }
/// <summary>
/// Gets the state of the button control.
/// </summary>
/// <value>The state of the button control.</value>
[Browsable(false)]
public PushButtonState State
{
get
{
if (!Enabled)
{
return PushButtonState.Disabled;
}
if (isPressed)
{
return PushButtonState.Pressed;
}
if (isHovered)
{
return PushButtonState.Hot;
}
if (isFocused || IsDefault)
{
return PushButtonState.Default;
}
return PushButtonState.Normal;
}
}
#endregion
#region " Events "
/// <summary>Occurs when the value of the <see cref="P:Glass.GlassButton.InnerBorderColor" /> property changes.</summary>
[Description("Event raised when the value of the InnerBorderColor property is changed."), Category("Property Changed")]
public event EventHandler InnerBorderColorChanged;
/// <summary>
/// Raises the <see cref="E:Glass.GlassButton.InnerBorderColorChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected virtual void OnInnerBorderColorChanged(EventArgs e)
{
if (InnerBorderColorChanged != null)
{
InnerBorderColorChanged(this, e);
}
}
/// <summary>Occurs when the value of the <see cref="P:Glass.GlassButton.OuterBorderColor" /> property changes.</summary>
[Description("Event raised when the value of the OuterBorderColor property is changed."), Category("Property Changed")]
public event EventHandler OuterBorderColorChanged;
/// <summary>
/// Raises the <see cref="E:Glass.GlassButton.OuterBorderColorChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected virtual void OnOuterBorderColorChanged(EventArgs e)
{
if (OuterBorderColorChanged != null)
{
OuterBorderColorChanged(this, e);
}
}
/// <summary>Occurs when the value of the <see cref="P:Glass.GlassButton.ShineColor" /> property changes.</summary>
[Description("Event raised when the value of the ShineColor property is changed."), Category("Property Changed")]
public event EventHandler ShineColorChanged;
/// <summary>
/// Raises the <see cref="E:Glass.GlassButton.ShineColorChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected virtual void OnShineColorChanged(EventArgs e)
{
if (ShineColorChanged != null)
{
ShineColorChanged(this, e);
}
}
/// <summary>Occurs when the value of the <see cref="P:Glass.GlassButton.GlowColor" /> property changes.</summary>
[Description("Event raised when the value of the GlowColor property is changed."), Category("Property Changed")]
public event EventHandler GlowColorChanged;
/// <summary>
/// Raises the <see cref="E:Glass.GlassButton.GlowColorChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected virtual void OnGlowColorChanged(EventArgs e)
{
if (GlowColorChanged != null)
{
InnerBorderColorChanged(this, e);
}
}
#endregion
#region " Overrided Methods "
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.SizeChanged" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnSizeChanged(EventArgs e)
{
CreateFrames();
base.OnSizeChanged(e);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Click" /> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
protected override void OnClick(EventArgs e)
{
isKeyDown = isMouseDown = false;
base.OnClick(e);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Enter" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnEnter(EventArgs e)
{
isFocused = isFocusedByKey = true;
base.OnEnter(e);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Leave" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
isFocused = isFocusedByKey = isKeyDown = isMouseDown = false;
Invalidate();
}
/// <summary>
/// Raises the <see cref="M:System.Windows.Forms.ButtonBase.OnKeyUp(System.Windows.Forms.KeyEventArgs)" /> event.
/// </summary>
/// <param name="kevent">A <see cref="T:System.Windows.Forms.KeyEventArgs" /> that contains the event data.</param>
protected override void OnKeyDown(KeyEventArgs kevent)
{
if (kevent.KeyCode == Keys.Space)
{
isKeyDown = true;
Invalidate();
}
base.OnKeyDown(kevent);
}
/// <summary>
/// Raises the <see cref="M:System.Windows.Forms.ButtonBase.OnKeyUp(System.Windows.Forms.KeyEventArgs)" /> event.
/// </summary>
/// <param name="kevent">A <see cref="T:System.Windows.Forms.KeyEventArgs" /> that contains the event data.</param>
protected override void OnKeyUp(KeyEventArgs kevent)
{
if (isKeyDown && kevent.KeyCode == Keys.Space)
{
isKeyDown = false;
Invalidate();
}
base.OnKeyUp(kevent);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseDown" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.</param>
protected override void OnMouseDown(MouseEventArgs e)
{
if (!isMouseDown && e.Button == MouseButtons.Left)
{
isMouseDown = true;
isFocusedByKey = false;
Invalidate();
}
base.OnMouseDown(e);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.</param>
protected override void OnMouseUp(MouseEventArgs e)
{
if (isMouseDown)
{
isMouseDown = false;
Invalidate();
}
base.OnMouseUp(e);
}
/// <summary>
/// Raises the <see cref="M:System.Windows.Forms.Control.OnMouseMove(System.Windows.Forms.MouseEventArgs)" /> event.
/// </summary>
/// <param name="mevent">A <see cref="T:System.Windows.Forms.MouseEventArgs" /> that contains the event data.</param>
protected override void OnMouseMove(MouseEventArgs mevent)
{
base.OnMouseMove(mevent);
if (mevent.Button != MouseButtons.None)
{
if (!ClientRectangle.Contains(mevent.X, mevent.Y))
{
if (isHovered)
{
isHovered = false;
Invalidate();
}
}
else if (!isHovered)
{
isHovered = true;
Invalidate();
}
}
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseEnter" /> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
protected override void OnMouseEnter(EventArgs e)
{
isHovered = true;
FadeIn();
Invalidate();
base.OnMouseEnter(e);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseLeave" /> event.
/// </summary>
/// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
protected override void OnMouseLeave(EventArgs e)
{
isHovered = false;
FadeOut();
Invalidate();
base.OnMouseLeave(e);
}
#endregion
#region " Painting "
/// <summary>
/// Raises the <see cref="M:System.Windows.Forms.ButtonBase.OnPaint(System.Windows.Forms.PaintEventArgs)" /> event.
/// </summary>
/// <param name="pevent">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data.</param>
protected override void OnPaint(PaintEventArgs pevent)
{
DrawButtonBackgroundFromBuffer(pevent.Graphics);
DrawForegroundFromButton(pevent);
DrawButtonForeground(pevent.Graphics);
}
private void DrawButtonBackgroundFromBuffer(Graphics graphics)
{
int frame;
if (!Enabled)
{
frame = FRAME_DISABLED;
}
else if (isPressed)
{
frame = FRAME_PRESSED;
}
else if (!isAnimating && currentFrame == 0)
{
frame = FRAME_NORMAL;
}
else
{
if (!HasAnimationFrames)
{
CreateFrames(true);
}
frame = FRAME_ANIMATED + currentFrame;
}
if (frames == null)
{
CreateFrames();
}
graphics.DrawImage(frames[frame], Point.Empty);
}
public Image CreateBackgroundFrame(bool pressed, bool hovered,
bool animating, bool enabled, float glowOpacity)
{
Rectangle rect = ClientRectangle;
if (rect.Width <= 0)
{
rect.Width = 1;
}
if (rect.Height <= 0)
{
rect.Height = 1;
}
Image img = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(img))
{
g.Clear(Color.Transparent);
DrawButtonBackground(g, rect, pressed, hovered, animating, enabled,
outerBorderColor, backColor, glowColor, shineColor, innerBorderColor,
glowOpacity);
}
return img;
}
private static void DrawButtonBackground(Graphics g, Rectangle rectangle,
bool pressed, bool hovered, bool animating, bool enabled,
Color outerBorderColor, Color backColor, Color glowColor, Color shineColor,
Color innerBorderColor, float glowOpacity)
{
SmoothingMode sm = g.SmoothingMode;
g.SmoothingMode = SmoothingMode.AntiAlias;
#region " white border "
Rectangle rect = rectangle;
rect.Width--;
rect.Height--;
using (GraphicsPath bw = CreateRoundRectangle(rect, 4))
{
using (Pen p = new Pen(outerBorderColor))
{
g.DrawPath(p, bw);
}
}
#endregion
rect.X++;
rect.Y++;
rect.Width -= 2;
rect.Height -= 2;
Rectangle rect2 = rect;
rect2.Height >>= 1;
#region " content "
using (GraphicsPath bb = CreateRoundRectangle(rect, 2))
{
int opacity = pressed ? 0xcc : 0x7f;
using (Brush br = new SolidBrush(Color.FromArgb(opacity, backColor)))
{
g.FillPath(br, bb);
}
}
#endregion
#region " glow "
if ((hovered || animating) && !pressed)
{
using (GraphicsPath clip = CreateRoundRectangle(rect, 2))
{
g.SetClip(clip, CombineMode.Intersect);
using (GraphicsPath brad = CreateBottomRadialPath(rect))
{
using (PathGradientBrush pgr = new PathGradientBrush(brad))
{
unchecked
{
int opacity = (int)(0xB2 * glowOpacity + .5f);
RectangleF bounds = brad.GetBounds();
pgr.CenterPoint = new PointF((bounds.Left + bounds.Right) / 2f, (bounds.Top + bounds.Bottom) / 2f);
pgr.CenterColor = Color.FromArgb(opacity, glowColor);
pgr.SurroundColors = new Color[] { Color.FromArgb(0, glowColor) };
}
g.FillPath(pgr, brad);
}
}
g.ResetClip();
}
}
#endregion
#region " shine "
if (rect2.Width > 0 && rect2.Height > 0)
{
rect2.Height++;
using (GraphicsPath bh = CreateTopRoundRectangle(rect2, 2))
{
rect2.Height++;
int opacity = 0x99;
if (pressed | !enabled)
{
opacity = (int)(.4f * opacity + .5f);
}
using (LinearGradientBrush br = new LinearGradientBrush(rect2, Color.FromArgb(opacity, shineColor), Color.FromArgb(opacity / 3, shineColor), LinearGradientMode.Vertical))
{
g.FillPath(br, bh);
}
}
rect2.Height -= 2;
}
#endregion
#region " black border "
using (GraphicsPath bb = CreateRoundRectangle(rect, 3))
{
using (Pen p = new Pen(innerBorderColor))
{
g.DrawPath(p, bb);
}
}
#endregion
g.SmoothingMode = sm;
}
private void DrawButtonForeground(Graphics g)
{
if (Focused && ShowFocusCues)
{
Rectangle rect = ClientRectangle;
rect.Inflate(-4, -4);
ControlPaint.DrawFocusRectangle(g, rect);
}
}
private Button imageButton;
private void DrawForegroundFromButton(PaintEventArgs pevent)
{
if (imageButton == null)
{
imageButton = new Button();
imageButton.Parent = new TransparentControl();
imageButton.BackColor = Color.Transparent;
imageButton.FlatAppearance.BorderSize = 0;
imageButton.FlatStyle = FlatStyle.Flat;
}
imageButton.AutoEllipsis = AutoEllipsis;
if (Enabled)
{
imageButton.ForeColor = ForeColor;
}
else
{
imageButton.ForeColor = Color.FromArgb((3*ForeColor.R + backColor.R) >> 2,
(3*ForeColor.G + backColor.G) >> 2,
(3*ForeColor.B + backColor.B) >> 2);
}
imageButton.Font = Font;
imageButton.RightToLeft = RightToLeft;
imageButton.Image = Image;
imageButton.ImageAlign = ImageAlign;
imageButton.ImageIndex = ImageIndex;
imageButton.ImageKey = ImageKey;
imageButton.ImageList = ImageList;
imageButton.Padding = Padding;
imageButton.Size = Size;
imageButton.Text = Text;
imageButton.TextAlign = TextAlign;
imageButton.TextImageRelation = TextImageRelation;
imageButton.UseCompatibleTextRendering = UseCompatibleTextRendering;
imageButton.UseMnemonic = UseMnemonic;
InvokePaint(imageButton, pevent);
}
class TransparentControl : Control
{
protected override void OnPaintBackground(PaintEventArgs pevent) { }
protected override void OnPaint(PaintEventArgs e) { }
}
private static GraphicsPath CreateRoundRectangle(Rectangle rectangle, int radius)
{
GraphicsPath path = new GraphicsPath();
int l = rectangle.Left;
int t = rectangle.Top;
int w = rectangle.Width;
int h = rectangle.Height;
int d = radius << 1;
path.AddArc(l, t, d, d, 180, 90); // topleft
path.AddLine(l + radius, t, l + w - radius, t); // top
path.AddArc(l + w - d, t, d, d, 270, 90); // topright
path.AddLine(l + w, t + radius, l + w, t + h - radius); // right
path.AddArc(l + w - d, t + h - d, d, d, 0, 90); // bottomright
path.AddLine(l + w - radius, t + h, l + radius, t + h); // bottom
path.AddArc(l, t + h - d, d, d, 90, 90); // bottomleft
path.AddLine(l, t + h - radius, l, t + radius); // left
path.CloseFigure();
return path;
}
private static GraphicsPath CreateTopRoundRectangle(Rectangle rectangle, int radius)
{
GraphicsPath path = new GraphicsPath();
int l = rectangle.Left;
int t = rectangle.Top;
int w = rectangle.Width;
int h = rectangle.Height;
int d = radius << 1;
path.AddArc(l, t, d, d, 180, 90); // topleft
path.AddLine(l + radius, t, l + w - radius, t); // top
path.AddArc(l + w - d, t, d, d, 270, 90); // topright
path.AddLine(l + w, t + radius, l + w, t + h); // right
path.AddLine(l + w, t + h, l, t + h); // bottom
path.AddLine(l, t + h, l, t + radius); // left
path.CloseFigure();
return path;
}
private static GraphicsPath CreateBottomRadialPath(Rectangle rectangle)
{
GraphicsPath path = new GraphicsPath();
RectangleF rect = rectangle;
rect.X -= rect.Width * .35f;
rect.Y -= rect.Height * .15f;
rect.Width *= 1.7f;
rect.Height *= 2.3f;
path.AddEllipse(rect);
path.CloseFigure();
return path;
}
#endregion
#region " Unused Properties & Events "
/// <summary>This property is not relevant for this class.</summary>
/// <returns>This property is not relevant for this class.</returns>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
public new FlatButtonAppearance FlatAppearance
{
get { return base.FlatAppearance; }
}
/// <summary>This property is not relevant for this class.</summary>
/// <returns>This property is not relevant for this class.</returns>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
public new FlatStyle FlatStyle
{
get { return base.FlatStyle; }
set { base.FlatStyle = value; }
}
/// <summary>This property is not relevant for this class.</summary>
/// <returns>This property is not relevant for this class.</returns>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
public new bool UseVisualStyleBackColor
{
get { return base.UseVisualStyleBackColor; }
set { base.UseVisualStyleBackColor = value; }
}
#endregion
#region " Animation Support "
private List<Image> frames;
private const int FRAME_DISABLED = 0;
private const int FRAME_PRESSED = 1;
private const int FRAME_NORMAL = 2;
private const int FRAME_ANIMATED = 3;
private bool HasAnimationFrames
{
get
{
return frames != null && frames.Count > FRAME_ANIMATED;
}
}
private void CreateFrames()
{
CreateFrames(false);
}
private void CreateFrames(bool withAnimationFrames)
{
DestroyFrames();
if (!IsHandleCreated)
{
return;
}
if (frames == null)
{
frames = new List<Image>();
}
frames.Add(CreateBackgroundFrame(false, false, false, false, 0));
frames.Add(CreateBackgroundFrame(true, true, false, true, 0));
frames.Add(CreateBackgroundFrame(false, false, false, true, 0));
if (!withAnimationFrames)
{
return;
}
for (int i = 0; i < framesCount; i++)
{
frames.Add(CreateBackgroundFrame(false, true, true, true, (float)i / (framesCount - 1F)));
}
}
private void DestroyFrames()
{
if (frames != null)
{
while (frames.Count > 0)
{
frames[frames.Count - 1].Dispose();
frames.RemoveAt(frames.Count - 1);
}
}
}
private const int animationLength = 300;
private const int framesCount = 10;
private int currentFrame;
private int direction;
private bool isAnimating
{
get
{
return direction != 0;
}
}
private void FadeIn()
{
direction = 1;
timer.Enabled = true;
}
private void FadeOut()
{
direction = -1;
timer.Enabled = true;
}
private void timer_Tick(object sender, EventArgs e)
{
if (!timer.Enabled)
{
return;
}
Refresh();
currentFrame += direction;
if (currentFrame == -1)
{
currentFrame = 0;
timer.Enabled = false;
direction = 0;
return;
}
if (currentFrame == framesCount)
{
currentFrame = framesCount - 1;
timer.Enabled = false;
direction = 0;
}
}
#endregion
}
}
同样还有水晶风格的:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.Data; using System.Text; using System.Windows.Forms; namespace MyControls { public partial class CrystalButton : Button { private enum MouseActionType { None, Hover, Click } private MouseActionType mouseAction; private ImageAttributes imgAttr = new ImageAttributes(); private Bitmap buttonBitmap; private Rectangle buttonBitmapRectangle; public CrystalButton() { InitializeComponent(); mouseAction = MouseActionType.None; this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true); //The following defaults are better suited to draw the text outline this.Font = new Font("Arial Black", 12, FontStyle.Bold); this.BackColor = Color.DarkTurquoise; this.Size = new Size(112, 48); } private GraphicsPath GetGraphicsPath(Rectangle rc, int r) { int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height; GraphicsPath path = new GraphicsPath(); path.AddArc(x, y, r, r, 180, 90); //Upper left corner path.AddArc(x + w - r, y, r, r, 270, 90); //Upper right corner path.AddArc(x + w - r, y + h - r, r, r, 0, 90); //Lower right corner path.AddArc(x, y + h - r, r, r, 90, 90); //Lower left corner path.CloseFigure(); return path; } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; //g.Clear(Color.White); g.Clear(SystemColors.ButtonFace ); Color clr = this.BackColor; int shadowOffset = 8; int btnOffset = 0; switch (mouseAction) { case MouseActionType.Click: shadowOffset = 4; clr = Color.LightGray; btnOffset = 2; break; case MouseActionType.Hover: clr = Color.LightGray; break; } g.SmoothingMode = SmoothingMode.AntiAlias; /// /// 创建按钮本身的图形 /// Rectangle rc = new Rectangle(btnOffset, btnOffset, this.ClientSize.Width - 8 - btnOffset, this.ClientSize.Height - 8 - btnOffset); GraphicsPath path1 = this.GetGraphicsPath(rc, 20); LinearGradientBrush br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rc.Height + 6), clr, Color.White); /// /// 创建按钮阴影 /// Rectangle rc2 = rc; rc2.Offset(shadowOffset, shadowOffset); GraphicsPath path2 = this.GetGraphicsPath(rc2, 20); PathGradientBrush br2 = new PathGradientBrush(path2); br2.CenterColor = Color.Black; br2.SurroundColors = new Color[] {SystemColors.ButtonFace}; //为了更逼真,我们将渐变结束颜色设定为窗体前景颜色,可以根据窗口的前景颜色适当调整 /// /// 创建按钮顶部白色渐变 /// Rectangle rc3 = rc; rc3.Inflate(-5, -5); rc3.Height = 15; GraphicsPath path3 = GetGraphicsPath(rc3, 20); LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical); /// /// 绘制图形 /// g.FillPath(br2, path2); //绘制阴影 g.FillPath(br1, path1); //绘制按钮 g.FillPath(br3, path3); //绘制顶部白色泡泡 /// ///设定内存位图对象,进行二级缓存绘图操作 /// buttonBitmapRectangle = new Rectangle(rc.Location, rc.Size); buttonBitmap = new Bitmap(buttonBitmapRectangle.Width, buttonBitmapRectangle.Height); Graphics g_bmp = Graphics.FromImage(buttonBitmap); g_bmp.SmoothingMode = SmoothingMode.AntiAlias; g_bmp.FillPath(br1, path1); g_bmp.FillPath(br3, path3); /// ///将region赋值给button Region rgn = new Region(path1); rgn.Union(path2); this.Region = rgn; /// /// 绘制按钮的文本 /// GraphicsPath path4 = new GraphicsPath(); RectangleF path1bounds = path1.GetBounds(); Rectangle rcText = new Rectangle((int)path1bounds.X + btnOffset, (int)path1bounds.Y + btnOffset, (int)path1bounds.Width, (int)path1bounds.Height); StringFormat strformat = new StringFormat(); strformat.Alignment = StringAlignment.Center; strformat.LineAlignment = StringAlignment.Center; path4.AddString(this.Text, this.Font.FontFamily, (int)this.Font.Style, this.Font.Size, rcText, strformat); Pen txtPen = new Pen(this.ForeColor , 1); g.DrawPath(txtPen, path4); g_bmp.DrawPath(txtPen, path4); } protected override void OnMouseDown(MouseEventArgs e) { if (e.Button == MouseButtons.Left) { this.mouseAction = MouseActionType.Click; this.Invalidate(); } base.OnMouseDown(e); } protected override void OnMouseUp(MouseEventArgs e) { this.mouseAction = MouseActionType.Hover; this.Invalidate(); base.OnMouseUp(e); } protected override void OnMouseHover(EventArgs e) { this.mouseAction = MouseActionType.Hover; this.Invalidate(); base.OnMouseHover(e); } protected override void OnMouseEnter(EventArgs e) { this.mouseAction = MouseActionType.Hover; this.Invalidate(); base.OnMouseEnter(e); } protected override void OnMouseLeave(EventArgs e) { this.mouseAction = MouseActionType.None; this.Invalidate(); base.OnMouseLeave(e); } } }
浙公网安备 33010602011771号