C# Winform实现圆角无锯齿按钮
作者:liaogaobo2008 发布时间:2022-08-30 01:11:56
标签: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);
}
}
来源:https://blog.csdn.net/liaogaobo2008/article/details/103649207
0
投稿
猜你喜欢
- java使用stream实现list中对象属性的合并:根据两个List中的某个相同字段合并成一条List,包含两个List中的字段一、前言为
- 一 介绍本节给知识追寻者给大家带来的是springSecurity入门篇,主要是简述下springSecrurity的启动原理和简单的入门搭
- 对于生成的sql语句 自动加上单引号的情况mybatis是这样的,如果表的字段跟系统字段冲突,写sql语句的时候必须得加上单引号,这样才会区
- @Autowired注解在抽象类中失效最近在工作中遇到这个问题,在抽象类中使用Autowired这个注解,注入mybatis的dao时,总是
- 本文实例讲述了C#创建临时文件的方法。分享给大家供大家参考。具体分析如下:C#可以通过Path.GetTempFileName获得一个临时文
- Apache Dubbo是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡
- kafka是什么?Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式
- 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出改进方
- springboot + docker + jenkins自动化部署项目,jenkins、mysql、redis都是docker运行的,并且
- 本文研究的主要是Java ArrayList扩容问题实例详解的相关内容,具体介绍如下。首先我们需要知道ArrayList里面的实质的其实是一
- 序列化和反序列化Java是面向对象的语言,与其他语言进行交互(比如与前端js进行http通信),需要把对象转化成一种通用的格式比如json(
- 首先 下载 jedis.jar包然后再 工程设置里面找到Libraries,点击+。添加下载好的jedis.jar包。点击OK退出即可创建J
- 本文实例为大家分享了iOS新浪微博分享功能的具体代码,供大家参考,具体内容如下做新浪分享 需先去http://open.weibo.com/
- 直接上代码,看下最简单也是最常用的方法,将Object 转为 JSON 以及将Json转为Object方式public class Test
- 前言:mybatisplus 可以说是对mybatis更好的拓展,一些简单的增删改查的操作已经被作者实现,我们只需引用即可。1.数据库建表这
- 什么是ByteBuddyByteBuddy是一个java的运行时代码生成库,他可以帮助你以字节码的方式动态修改java类的代码。为什么需要B
- LinkedListLinkedList是一种可以在任何位置进行高效地插入和删除操作的有序序列。它的最基本存储结构是一个节点:每个节点将存储
- idea pom文件图标不对今天遇到一个奇怪的现象,如下图原先pom的图标应该是有个m的,现在直接变成了xml的文件了。右边的Maven P
- mysql插件实现原理官网的关键信息参考文档https://mybatis.org/mybatis-3/zh/configuration.h
- Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态。Memento模式相