感谢您阅读我的博客,如果您现在工作、学习累了或者疲惫了,不妨聆听一下音乐,它能够减轻你的疲劳,还能够带给您一种舒适愉悦的心情。如果您认为这篇文章还不错或者有所收获,您可以在页面 右侧和底部 扫描二维码 打赏我,您的鼓励是我继续写作、分享的最大动力!

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.运行效果

posted @ 2019-07-18 22:05  Love In Winter  阅读(543)  评论(0编辑  收藏  举报
作者: LifeDecidesHappiness
出处: http://www.cnblogs.com/LifeDecidesHappiness/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址 2468881301@qq.com  联系我,非常感谢。
踏实做一个为人民服务的搬运工!
如果您认为这篇文章还不错或者有所收获,您可以通过右边的“打赏”功能,您的支持和鼓励是我继续写作、分享的最大动力!

点击关注不迷路,让我带你上高速!