作者: DD2013
查看: 110164|回复: 74
打印 上一主题 下一主题

[教程] 【圆角按钮美化】C# winform中 Button 美化(圆角)

  [复制链接]
跳转到指定楼层
楼主
DD2013 发表于 2015-1-11 17:13:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
查看: 110164|回复: 74
说明:
还是老规矩,先上效果图。

效果图:


思路和代码:
(代码比较乱,自己稍微整理下就可以使用,不传全部源代码了,防止伸手党)
[C#] 纯文本查看 复制代码
public  class ButtonEx : Button
    {
        private Color _baseColor = Color.FromArgb(51, 161, 224);//基颜色
        private ControlState _controlState;//控件状态
        private int _imageWidth = 18;
        private RoundStyle _roundStyle = RoundStyle.All;//圆角
        private int _radius = 8;                        //圆角半径

        public ButtonEx(): base()
        {
            this.SetStyle(
                ControlStyles.UserPaint |  //控件自行绘制,而不使用操作系统的绘制
                ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。
                ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。
                ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。                  
                ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色
        }

        [DefaultValue(typeof(Color), "51, 161, 224")]
        public Color BaseColor
        {
            get { return _baseColor; }
            set
            {
                _baseColor = value;
                base.Invalidate();
            }
        }
        [DefaultValue(18)]//默认值为18px,最小12px
        public int ImageWidth
        {
            get { return _imageWidth; }
            set
            {
                if (value != _imageWidth)
                {

                    _imageWidth = value < 12 ? 12 : value;
                    base.Invalidate();
                }
            }
        }
        [DefaultValue(typeof(RoundStyle), "1")]//默认全部都是圆角
        public RoundStyle RoundStyle
        {
            get { return _roundStyle; }
            set
            {
                if (_roundStyle != value)
                {
                    _roundStyle = value;
                    base.Invalidate();
                }
            }
        }
        [DefaultValue(8)]//设置圆角半径,默认值为8,最小值为4px
        public int Radius
        {
            get { return _radius; }
            set
            {
                if (_radius != value)
                {
                    _radius = value < 4 ? 4 : value;
                    base.Invalidate();
                }
            }
        }
        internal ControlState ControlState  //控件的状态
        {
            get { return _controlState; }
            set
            {
                if (_controlState != value)
                {
                    _controlState = value;
                    base.Invalidate();
                }
            }
        }
        protected override void OnMouseEnter(EventArgs e)//鼠标进入时
        {
            base.OnMouseEnter(e);
            ControlState = ControlState.Hover;//正常
        }
        protected override void OnMouseLeave(EventArgs e)//鼠标离开
        {
            base.OnMouseLeave(e);
            ControlState = ControlState.Normal;//正常
        }
        protected override void OnMouseDown(MouseEventArgs e)//鼠标按下
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left && e.Clicks == 1)//鼠标左键且点击次数为1
            {
                ControlState = ControlState.Pressed;//按下的状态
            }
        }
        protected override void OnMouseUp(MouseEventArgs e)//鼠标弹起
        {
            base.OnMouseUp(e);
            if (e.Button == MouseButtons.Left && e.Clicks == 1)
            {
                if (ClientRectangle.Contains(e.Location))//控件区域包含鼠标的位置
                {
                    ControlState = ControlState.Hover;
                }
                else
                {
                    ControlState = ControlState.Normal;
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            base.OnPaintBackground(e);

            Graphics g = e.Graphics;
            Rectangle imageRect;//图像区域
            Rectangle textRect;//文字区域

            this.CalculateRect(out imageRect, out textRect);

            g.SmoothingMode = SmoothingMode.AntiAlias;

            Color baseColor;
            Color borderColor;
            Color innerBorderColor = this._baseColor;//Color.FromArgb(200, 255, 255, 255); ;

            if (Enabled)
            {
                switch (ControlState)
                {
                    case ControlState.Hover:
                        baseColor = GetColor(_baseColor, 0, -35, -24, -30);
                        borderColor = _baseColor;
                        break;
                    case ControlState.Pressed:
                        baseColor = GetColor(_baseColor, 0, -35, -24, -9);
                        borderColor = _baseColor;
                        break;
                    default:
                        baseColor = _baseColor;
                        borderColor = _baseColor;
                        break;
                }
            }
            else
            {
                baseColor = SystemColors.ControlDark;
                borderColor = SystemColors.ControlDark;
            }

            this.RenderBackgroundInternal(
                g,
                ClientRectangle,
                baseColor,
                borderColor,
                innerBorderColor,
                RoundStyle,
                Radius,
                0.35f,
                false,
                true,
                LinearGradientMode.Vertical);

            if (Image != null)
            {
                g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                g.DrawImage(Image,imageRect,0,0,Image.Width,Image.Height,GraphicsUnit.Pixel);
            }
            TextRenderer.DrawText(g,Text,Font,textRect,ForeColor,GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
        }


        private Color GetColor(Color colorBase, int a, int r, int g, int b)
        {
            int a0 = colorBase.A;
            int r0 = colorBase.R;
            int g0 = colorBase.G;
            int b0 = colorBase.B;
            if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
            if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
            if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
            if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }

            return Color.FromArgb(a, r, g, b);
        }


        internal void RenderBackgroundInternal(
               Graphics g,
               Rectangle rect,
               Color baseColor,
               Color borderColor,
               Color innerBorderColor,
               RoundStyle style,
               int roundWidth,//圆角半径
               float basePosition,
               bool drawBorder,
               bool drawGlass,
               LinearGradientMode mode)
        {
            if (drawBorder)//是否画边框
            {
                rect.Width--;
                rect.Height--;
            }

            using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
            {
                Color[] colors = new Color[4];
                colors[0] = GetColor(baseColor, 0, 35, 24, 9);
                colors[1] = GetColor(baseColor, 0, 0, 0, 0);
                colors[2] = baseColor;
                colors[3] = GetColor(baseColor, 0, 0 ,0 ,0);

                ColorBlend blend = new ColorBlend();
                blend.Positions = new float[] { 0.0f, basePosition, basePosition, 1.0f };
                blend.Colors = colors;
                brush.InterpolationColors = blend;
                if (style != RoundStyle.None)
                {
                    using (GraphicsPath path =
                        GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
                    {
                        g.FillPath(brush, path);
                    }

                    if (baseColor.A > 80)
                    {
                        Rectangle rectTop = rect;

                        if (mode == LinearGradientMode.Vertical)
                        {
                           // rectTop.Height = (int)(rectTop.Height * basePosition);
                        }
                        else
                        {
                           // rectTop.Width = (int)(rect.Width * basePosition);
                        }
                        using (GraphicsPath pathTop = GraphicsPathHelper.CreatePath(
                            rectTop, roundWidth, RoundStyle.Top, false))
                        {
                            using (SolidBrush brushAlpha =
                                new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
                            {
                                g.FillPath(brushAlpha, pathTop);
                            }
                        }
                    }

                }


评分

参与人数 11金钱 +14 收起 理由
gzsfz + 1 赞一个!
U_King + 1 赞一个!
linshida114 + 1
茄子绝杀 + 1
jobfind + 2 很给力!
leroy_pang + 1 感谢LZ对论坛做出的贡献~
陈大仙sunmmer + 1
林夕子 + 1 感谢LZ对论坛做出的贡献~
zakailynn + 1 赞一个!
iNIC + 1
乔克斯 + 3 感谢LZ对论坛做出的贡献~

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏33 转播转播
回复 论坛版权

使用道具 举报

沙发
CastleDrv 发表于 2015-1-11 19:16:08 | 只看该作者
支持一个
回复

使用道具 举报

板凳
ck261310 发表于 2015-1-11 20:50:04 | 只看该作者
漂亮,学习了
地板
mumupudding 发表于 2015-1-12 13:34:41 | 只看该作者
代码不完整啊,还有引用不明确,没法使用
5#
乔克斯 发表于 2015-1-13 10:14:04 | 只看该作者
鉴于论坛中熟悉GDI+绘制的比较少,楼主不介意的话还是放出源码~有助于大家学习哦。
6#
xiaobo 发表于 2015-1-18 02:07:20 | 只看该作者
漂亮!
回复

使用道具 举报

7#
wuxunhua 发表于 2015-2-9 15:54:59 | 只看该作者
下来看看
回复

使用道具 举报

8#
wuxunhua 发表于 2015-2-9 15:55:31 | 只看该作者
下来看看,学习下。
9#
zoney88 发表于 2015-2-13 19:36:53 | 只看该作者
挺漂亮,不知闪烁不
10#
wmvsmm 发表于 2015-3-12 10:55:27 | 只看该作者
mark button
您需要登录后才可以回帖 登录 | 加入CSkin博客

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2024-11-16 08:30, Processed in 0.572638 second(s), 34 queries , Gzip On.

快速回复 返回顶部 返回列表