WinForm自制水晶按钮
1.代码结构
2.实现代码
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace WinFormBeautyButtonDemo { /// <summary> /// WinForm自制水晶按钮(很漂亮) /// LDH @ 2019-7-18 /// </summary> public sealed partial class BeautyButton : Button { /// <summary> /// 定义一个位图 /// </summary> private Bitmap _btnbmp; /// <summary> /// 定义一个矩形 /// </summary> 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); } /// <summary> /// 按钮形状 /// </summary> /// <param name="rc">按钮的坐标和大小</param> /// <param name="r">按钮圆弧的半径</param> /// <returns>返回按钮形状</returns> 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); } /// <summary> /// 鼠标离开事件 /// </summary> /// <param name="e"></param> protected override void OnMouseLeave(EventArgs e) { _mouseActionType = MouseActionType.None; Invalidate(); base.OnMouseLeave(e); } private enum MouseActionType { None, Hover, Click } } }
3.运行效果
本文作者:Love In Winter
本文链接:https://www.cnblogs.com/LifeDecidesHappiness/p/11210336.html
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以扫一扫,任意打赏,您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/LifeDecidesHappiness/p/11210336.html
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以扫一扫,任意打赏,您的鼓励是博主的最大动力!
![扫一扫,支付宝打赏](https://files.cnblogs.com/files/LifeDecidesHappiness/%E6%94%AF%E4%BB%98%E5%AE%9D.bmp)
![扫一扫,微信打赏](https://files.cnblogs.com/files/LifeDecidesHappiness/%E5%BE%AE%E4%BF%A1%E6%94%B6%E6%AC%BE%E7%A0%81.bmp)