C# Winform实现圆角无锯齿按钮

 更新时间:2022年08月29日 09:24:10   作者:liaogaobo2008  
这篇文章主要介绍了C# Winform实现圆角无锯齿按钮,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下

前言:

发现用Winform做一个圆角按钮遇到麻烦,主要是锯齿问题,后面想了想办法解决问题了。

主要方法是按钮的区域通过Region指定,但按钮需要自己画,否则怎么搞都出现锯齿,网上有朋友提供一个漂亮的方案,可是代码不完整无法使用,我的解决方案现在分享如下:

  public enum ControlState { Hover , Normal, Pressed }
    public class RoundButton : Button
    {
             private int radius;//半径 
        private Color _baseColor = Color.FromArgb(51, 161, 224);//基颜色
        private Color _hoverColor= Color.FromArgb(51, 0, 224);//基颜色
        private Color _normalColor = Color.FromArgb(0, 161, 224);//基颜色
        private Color _pressedColor = Color.FromArgb(51, 161, 0);//基颜色
        //圆形按钮的半径属性
        [CategoryAttribute("布局"), BrowsableAttribute(true), ReadOnlyAttribute(false)]
        public int Radius
        {
            set
            {
                radius = value;
                this.Invalidate();
            }
            get
            {
                return radius;
            }
        }
        [DefaultValue(typeof(Color), "51, 161, 224")]
        public Color NormalColor
        {
            get
            {
                return this._normalColor;
            }
            set
            {
                this._normalColor = value;
                this.Invalidate();
            }
        }
      //  [DefaultValue(typeof(Color), "220, 80, 80")]
        public Color HoverColor {
            get
            {
                return this._hoverColor;
            }
            set
            {
                this._hoverColor = value;
                this.Invalidate();
            }
        }
 
      //  [DefaultValue(typeof(Color), "251, 161, 0")]
        public Color PressedColor {
            get
            {
                return this._pressedColor;
            }
            set
            {
                this._pressedColor = value;
                this.Invalidate();
            }
        }
        public ControlState ControlState { get; set; }
        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;
                }
            }
        }
        public RoundButton()
        {
            Radius = 15;
            this.FlatStyle = FlatStyle.Flat;
            this.FlatAppearance.BorderSize = 0;
            this.ControlState = ControlState.Normal;
            this.SetStyle(
             ControlStyles.UserPaint |  //控件自行绘制,而不使用操作系统的绘制
             ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。
             ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。
             ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。                  
             ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色
        }
 
        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);
        }
 
        //重写OnPaint
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaint(e);
            base.OnPaintBackground(e);
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
 
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
 
            Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
            var path = GetRoundedRectPath(rect, radius);
 
            this.Region = new Region(path);
 
            Color baseColor;
            //Color borderColor;
            //Color innerBorderColor = this._baseColor;//Color.FromArgb(200, 255, 255, 255); ;
 
            switch (ControlState)
            {
                case ControlState.Hover:
                    baseColor = this.HoverColor;
                    break;
                case ControlState.Pressed:
                    baseColor = this.PressedColor;
                    break;
                case ControlState.Normal:
                    baseColor = this.NormalColor;
                    break;
                default:
                    baseColor = this.NormalColor;
                    break;
            }
 
            using (SolidBrush b = new SolidBrush(baseColor))
            {
                e.Graphics.FillPath(b, path);
                Font fo = new Font("宋体", 10.5F);
                Brush brush = new SolidBrush(this.ForeColor);
                StringFormat gs = new StringFormat();
                gs.Alignment = StringAlignment.Center; //居中
                gs.LineAlignment = StringAlignment.Center;//垂直居中
                e.Graphics.DrawString(this.Text, fo, brush, rect, gs);
                //  e.Graphics.DrawPath(p, path);
            }
        }
        private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            int diameter = radius;
            Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
            GraphicsPath path = new GraphicsPath();
            path.AddArc(arcRect, 180, 90);
            arcRect.X = rect.Right - diameter;
            path.AddArc(arcRect, 270, 90);
            arcRect.Y = rect.Bottom - diameter;
            path.AddArc(arcRect, 0, 90);
            arcRect.X = rect.Left;
            path.AddArc(arcRect, 90, 90);
            path.CloseFigure();
            return path;
        }
         protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
        }
    }

到此这篇关于C# Winform实现圆角无锯齿按钮的文章就介绍到这了,更多相关C# Winform内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Unity 数据存储和读取的方法汇总

    Unity 数据存储和读取的方法汇总

    这篇文章主要介绍了Unity 数据存储和读取的方法,本文通过四种方法在 Unity 中实现数据存储和读取方法的案例内容,结合示例代码给大家讲解的非常详细,需要的朋友可以参考下
    2022-10-10
  • Unity实现卡片循环滚动效果的示例详解

    Unity实现卡片循环滚动效果的示例详解

    这篇文章主要为大家详细介绍了如何利用Unity实现卡片循环滚动的效果,文中的实现步骤讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2022-12-12
  • c# 实现网页加载后将页面截取为长图片

    c# 实现网页加载后将页面截取为长图片

    这篇文章主要介绍了c# 实现网页加载后将页面截取为长图片的方法,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2021-01-01
  • C#获取文件名和文件路径的两种实现方式

    C#获取文件名和文件路径的两种实现方式

    这篇文章主要介绍了C#获取文件名和文件路径的两种实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • c# Struct的一些问题分析

    c# Struct的一些问题分析

    在 C# 中,结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct 关键字用于创建结构体。结构体是用来代表一个记录。
    2021-06-06
  • C#中的Task.Delay()和Thread.Sleep()区别(代码案例)

    C#中的Task.Delay()和Thread.Sleep()区别(代码案例)

    Task.Delay(),async/await和CancellationTokenSource组合起来使用可以实现可控制的异步延迟。本文通过多种代码案例给大家分析C#中的Task.Delay()和Thread.Sleep()知识,感兴趣的朋友一起看看吧
    2021-06-06
  • Unity实现全屏截图以及QQ截图

    Unity实现全屏截图以及QQ截图

    这篇文章主要为大家详细介绍了Unity实现全屏截图以及QQ截图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#实现两接口中同名方法实例分析

    C#实现两接口中同名方法实例分析

    这篇文章主要介绍了C#实现两接口中同名方法,涉及C#接口与方法的相关操作技巧,需要的朋友可以参考下
    2015-05-05
  • c#菜单动态合并的实现方法

    c#菜单动态合并的实现方法

    这篇文章主要介绍了c#菜单动态合并的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • C#实现插入排序算法实例

    C#实现插入排序算法实例

    这篇文章主要介绍了C#实现插入排序算法,实例分析了插入排序算法的原理与实现技巧,需要的朋友可以参考下
    2015-05-05

最新评论