1.代码结构
2.实现代码
using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Windows.Forms;namespace WinFormBeautyButtonDemo{ ////// WinForm自制水晶按钮(很漂亮) /// LDH @ 2019-7-18 /// public sealed partial class BeautyButton : Button { ////// 定义一个位图 /// private Bitmap _btnbmp; ////// 定义一个矩形 /// private Rectangle _btnrc; private MouseActionType _mouseActionType; public BeautyButton() { InitializeComponent(); _mouseActionType = MouseActionType.None; SetStyle(ControlStyles.AllPaintingInWmPaint | // 禁止擦除背景 ControlStyles.DoubleBuffer | // 双缓冲 ControlStyles.UserPaint, true); // 下面这些可以不设置,也可以自己定义 Font = new Font("微软雅黑", 12, FontStyle.Bold); BackColor = Color.DarkTurquoise; 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; var path = new GraphicsPath(); path.AddArc(x, y, r, r, 180, 90); // 左上角圆弧 path.AddArc(x + w - r, y, r, r, 270, 90); // 右上角圆弧 path.AddArc(x + w - r, y + h - r, r, r, 0, 90); // 右下角圆弧 path.AddArc(x, y + h - r, r, r, 90, 90); // 左下角圆弧 path.CloseFigure(); // 闭合 return path; } protected override void OnPaint(PaintEventArgs pe) { // base.OnPaint(pe); var g = pe.Graphics; // 创建画布 g.Clear(SystemColors.ButtonFace); // 重置背景颜色,可以自定义 var clr = BackColor; var btnOff = 0; // 按钮边距 var shadowOff = 0; // 阴影边距 switch (_mouseActionType) { case MouseActionType.None: break; case MouseActionType.Hover: clr = Color.LightGray; break; case MouseActionType.Click: shadowOff = 4; clr = Color.LightGray; btnOff = 2; break; } g.SmoothingMode = SmoothingMode.AntiAlias; // 消除锯齿 // 创建按钮本身的图形 var rc1 = new Rectangle(btnOff, btnOff, ClientSize.Width - 8 - btnOff, ClientSize.Height - 8 - btnOff); var path1 = GetGraphicsPath(rc1, 20); var br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rc1.Height + 6), clr, Color.White); // 创建按钮阴影 var rc2 = rc1; rc2.Offset(shadowOff, shadowOff); var path2 = GetGraphicsPath(rc2, 20); var br2 = new PathGradientBrush(path2) { CenterColor = Color.Black, SurroundColors = new[] {SystemColors.ButtonFace} }; // 为了更逼真,我们将渐变结束颜色设定为窗体前景色,可以根据窗口的前景颜色适当调整 // 创建按钮顶部白色渐变 var rc3 = rc1; rc3.Inflate(-5, -5); rc3.Height = 15; var path3 = GetGraphicsPath(rc3, 20); var 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); // 绘制顶部白色泡泡 // 设定内存位图对象,进行二级缓存绘图操作 _btnrc = new Rectangle(rc1.Location, rc1.Size); _btnbmp = new Bitmap(_btnrc.Width, _btnrc.Height); var gBmp = Graphics.FromImage(_btnbmp); gBmp.SmoothingMode = SmoothingMode.AntiAlias; gBmp.FillPath(br1, path1); gBmp.FillPath(br3, path3); // 将region赋值给button var rgn = new Region(path1); rgn.Union(path2); Region = rgn; // 绘制按钮的文本 var path4 = new GraphicsPath(); var path1Bounds = path1.GetBounds(); var rcText = new Rectangle((int) path1Bounds.X + btnOff, (int) path1Bounds.Y + btnOff, (int) path1Bounds.Width, (int) path1Bounds.Height); var strFormat = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; // 横竖都居中 path4.AddString(Text, Font.FontFamily, (int) Font.Style, Font.Size, rcText, strFormat); var txtPen = new Pen(ForeColor, 1); g.DrawPath(txtPen, path4); gBmp.DrawPath(txtPen, path4); } protected override void OnMouseDown(MouseEventArgs eventArgs) { if (eventArgs.Button == MouseButtons.Left) { _mouseActionType = MouseActionType.Click; Invalidate(); } base.OnMouseDown(eventArgs); } protected override void OnMouseUp(MouseEventArgs eventArgs) { _mouseActionType = MouseActionType.Hover; Invalidate(); base.OnMouseUp(eventArgs); } protected override void OnMouseHover(EventArgs e) { _mouseActionType = MouseActionType.Hover; Invalidate(); base.OnMouseHover(e); } protected override void OnMouseEnter(EventArgs e) { _mouseActionType = MouseActionType.Hover; Invalidate(); base.OnMouseEnter(e); } ////// 鼠标离开事件 /// /// protected override void OnMouseLeave(EventArgs e) { _mouseActionType = MouseActionType.None; Invalidate(); base.OnMouseLeave(e); } private enum MouseActionType { None, Hover, Click } }}
3.运行效果