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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C# Winform实现进度条显示

    本文实例为大家分享了C# Winform实现进度条显示的具体代码,供大家参考,具体内容如下 创建一个窗体,命名为StartForm 添加一个timer控件并更改名字为timerStart 添加一个ProgressBar控件,并调整一下属性: StartForm窗体的代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Draw

  • C# winform 请求http的实现(get,post)

    目录 一:.Net中有两个类 HttpWebRequest 和HttpWebResponse 类来实现Http的请求 二: HTTP定义了与服务器交互的不同方法 POST与GET的差异 两个简单的Get请求和Post请求 1.Get请求 2.Post请求 一个小测试 一:.Net中有两个类 HttpWebRequest 和HttpWebResponse 类来实现Http的请求 实现步骤: 1.通过WebRequest类创建一个HttpWebRequest的对象,该对象可以包含Http请求信息.2

  • C# Winform消息通知系统托盘气泡提示框ToolTip控件

    目录 气球状提示框的介绍和系统通知变化 消息通知的提示 ShowBalloonTip()方法及指定消息类型 NotifyIcon属性设置消息 BalloonTipIcon不同的消息类型 ToolTipText属性 ToolTip提示控件显式或主动的提示消息 一个ToolTip同时为多个控件设置提示 显式设置ToolTip 气球状提示框的介绍和系统通知变化 NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示任务栏中一定时间的具有指定标题.消息内容和

  • C# Winform消息通知之系统本地通知local toast notification

    目录 引言 toast 通知的结构 发送本地toast通知的操作步骤 安装NuGet包Microsoft.Toolkit.Uwp.Notifications 通知的发送(文本通知) 处理点击通知的操作 通知的卸载 设置通知的过期时间 .NET应用使用Toast Notifications(.NET5+) 添加图像 使用http图像 内联图像和主图 徽标和剪裁(圆形图片) UWP使用http图片 替换或删除指定通知 为 toast 设置主键 根据Tag和Group删除或替换toast 清除通知 引

  • C# Winform实现自定义漂亮的通知效果

    目录 前言 优化调整 调用并显示自定义通知 主要实现过程 代码实现 前言 本文主要介绍其具体的实现思路(视频仅有代码输入,并无过程介绍等),同时,在原本实现的基础上,进行了多处修改和优化,具体参见下面的内容. 优化调整 下面是对源代码的修改.优化和调整: 修改 lblMsg(Label) 的 AutoSize 为false,尽可能多占通知窗体区域,Anchor跟随窗体变换,文字左侧垂直居中,用于显示可能更多的消息. 设定action.timer1默认值,Name.Opacity.StartPos

  • C# WinForm制作登录界面的实现步骤

    在[解决方案资源管理器]中找到Form1.cs,单击,快捷键F2重命名为“Login.cs”(命名很重要,不然之后项目多了根据不知道哪个项目的内容是什么) 对窗体[Text]属性.[size]属性和[FormBoardStyle]属性进行修改 添加一个新的窗体 Ctrl+Shift+A,在弹出框中选择[Windows窗体],命名为main.cs 取消登录界面最大化最小化关闭按钮在父窗体菜单栏上显示最大化:MaximizeBox,最小化:MinimizeBox如果设置一个为False 的时候会显示

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

    本文实例为大家分享了C# Winform实现圆角无锯齿按钮的具体代码,供大家参考,具体内容如下 发现用Winform做一个圆角按钮遇到麻烦,主要是锯齿问题,后面想了想办法解决问题了. 主要方法是按钮的区域通过Region指定,但按钮需要自己画,否则怎么搞都出现锯齿,网上有朋友提供一个漂亮的方案,可是代码不完整无法使用,我的解决方案现在分享如下: 代码: public enum ControlState { Hover , Normal, Pressed }     public class Ro

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

    前言: 发现用Winform做一个圆角按钮遇到麻烦,主要是锯齿问题,后面想了想办法解决问题了. 主要方法是按钮的区域通过Region指定,但按钮需要自己画,否则怎么搞都出现锯齿,网上有朋友提供一个漂亮的方案,可是代码不完整无法使用,我的解决方案现在分享如下: public enum ControlState { Hover , Normal, Pressed } public class RoundButton : Button { private int radius;//半径 private

  • jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码

    本文实例讲述了jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码.分享给大家供大家参考.具体如下: 这里实现圆角表单,圆角输入框,无刷新验证,漂亮唯美,是对这款基于HTML5/CSS3/jQuery来实现的表单效果的简要概括,用HTML5可以实现很多超乎寻常的效果,从此你会喜欢上HTML5,会骂一下万恶的IE,到现在IE8还不支持HTML5,正悲哀着呢. 先来看看运行效果截图: 在线演示地址如下: http://demo.jb51.net/js/2015/jquery-htm

  • Winform窗体圆角设计代码

    网上看到的很多winform窗体圆角设计代码都比较累赘,这里分享一个少量代码就可以实现的圆角.主要运用了System.Drawing.Drawing2D. 效果图 代码如下 private void BeautiLoginForm_Paint(object sender, PaintEventArgs e) { Type(this, 25, 0.1); } private void Type(Control sender, int p_1, double p_2) { GraphicsPath

  • WinForm绘制圆角的方法

    本文实例讲述了WinForm绘制圆角的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.In

  • Android 详解自定义圆角输入框和按钮的实现流程

    Android-自定义圆角输入框和按钮 我们的征程是星辰大海,而非人间烟尘 自定义圆角输入框 效果 1.在drawable/下面new Drawable Resources File 2.新建shape文件,在里面自定义xml文件样式 代码文件 <!-- res/drawable/button_shape_normal.xml --> <shape xmlns:android="http://schemas.android.com/apk/res/android" a

  • C#中Winform 实现Ajax效果自定义按钮

    技术看点 WinForm自定义控件的使用 自定义控件gif动画的播放 需求及效果 又来一波 C# GDI自定义控件show .这个控件已经使用几年了,最近找出来重构一下.原来是没有边框的,那么导致导航的功能不是很突出.本来想加个效果:在执行单击时显示Loading动画,在执行完单击事件后恢复原样.这就是网页里见到的局部刷新,Ajax常用的场景.需求来自几年前一个智能储物柜项目,人机界面有个美工设计好的效果图,为了省事和通用,需要一个透明的按钮来实现导航的任务.就是控件只是设计时可见,运行时不可见

  • Winform控件优化之圆角按钮1

    目录 前言 圆角按钮实现[重写OnPaint实现圆角绘制] 代码主要关键点或思路.优化 使用圆角按钮 利用填充内外两层圆角矩形路径形成Border 通过缩放实现正确的内外两层圆角矩形路径 CDI+路径的填充模式 直接绘制路径作为边框[推荐]** 可以改进和实现的 在Paint事件中重绘控件为圆角 前言 Windows 11下所有控件已经默认采用圆角,其效果更好.相对有着更好的优化,只是这是默认的行为,无法进一步自定义. 圆角按钮实现[重写OnPaint实现圆角绘制] 控件自定义绘制的关键在于:重

  • Winform控件优化之圆角按钮2

    目录 前言 圆角按钮实现的进一步优化 主要功能[圆角方面] OnPaint方法中不要使用e.ClipRectangle 重新创建Region的锯齿问题和优势 代码具体实现 测试扩展按钮控件ButtonPro TextRenderer.DrawText绘制文本 使用StringFormat.GenericTypographic 仅仅重写OnPaintBackground 使用TextRenderer.DrawText绘制文本 前言 接上一篇Winform控件优化之圆角按钮1继续介绍圆角按钮的实现和

  • Winform控件优化Paint事件实现圆角组件及提取绘制圆角的方法

    目录 前言 Paint事件中实现圆角控件 提取绘制圆角矩形和旁边小尖角的代码为扩展方法 介绍 扩展方法 测试尖角的显示位置 重绘控件后文本的处理 同时重绘文本 通过添加Label控件实现对文本的处理[有尖角时需要额外处理] Paint事件中绘制圆角的优点 窗体失去焦点时按钮外观边框问题 Paint事件中绘制控件的问题[不要使用(事件)参数e.ClipRectangle] 前言 Windows 11下所有控件已经默认采用圆角,其效果更好.相对有着更好的优化,只是这是默认的行为,无法进一步自定义.

随机推荐