C#?Winform實(shí)現(xiàn)圓角無(wú)鋸齒按鈕
前言:
發(fā)現(xiàn)用Winform做一個(gè)圓角按鈕遇到麻煩,主要是鋸齒問(wèn)題,后面想了想辦法解決問(wèn)題了。
主要方法是按鈕的區(qū)域通過(guò)Region指定,但按鈕需要自己畫(huà),否則怎么搞都出現(xiàn)鋸齒,網(wǎng)上有朋友提供一個(gè)漂亮的方案,可是代碼不完整無(wú)法使用,我的解決方案現(xiàn)在分享如下:

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)//鼠標(biāo)進(jìn)入時(shí)
{
base.OnMouseEnter(e);
ControlState = ControlState.Hover;//正常
}
protected override void OnMouseLeave(EventArgs e)//鼠標(biāo)離開(kāi)
{
base.OnMouseLeave(e);
ControlState = ControlState.Normal;//正常
}
protected override void OnMouseDown(MouseEventArgs e)//鼠標(biāo)按下
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left && e.Clicks == 1)//鼠標(biāo)左鍵且點(diǎn)擊次數(shù)為1
{
ControlState = ControlState.Pressed;//按下的狀態(tài)
}
}
protected override void OnMouseUp(MouseEventArgs e)//鼠標(biāo)彈起
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left && e.Clicks == 1)
{
if (ClientRectangle.Contains(e.Location))//控件區(qū)域包含鼠標(biāo)的位置
{
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 | //控件自行繪制,而不使用操作系統(tǒng)的繪制
ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,減少閃爍。
ControlStyles.OptimizedDoubleBuffer |//在緩沖區(qū)上繪制,不直接繪制到屏幕上,減少閃爍。
ControlStyles.ResizeRedraw | //控件大小發(fā)生變化時(shí),重繪。
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);
}
//重寫(xiě)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);
}
}到此這篇關(guān)于C# Winform實(shí)現(xiàn)圓角無(wú)鋸齒按鈕的文章就介紹到這了,更多相關(guān)C# Winform內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# 三種方式實(shí)現(xiàn)Socket數(shù)據(jù)接收
這篇文章主要給大家分享三種實(shí)現(xiàn)C# 實(shí)現(xiàn)Socket數(shù)據(jù)接收的方式,接下倆小編就來(lái)為大家詳細(xì)介紹吧,需要的朋友可以參考一下2021-10-10
Unity Shader實(shí)現(xiàn)翻書(shū)效果
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)翻書(shū)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
C#使用Socket快速判斷數(shù)據(jù)庫(kù)連接是否正常的方法
這篇文章主要介紹了C#使用Socket快速判斷數(shù)據(jù)庫(kù)連接是否正常的方法,涉及C#中socket操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
C#調(diào)用SQL語(yǔ)句時(shí)乘號(hào)的用法
這篇文章主要介紹了C#調(diào)用SQL語(yǔ)句時(shí)乘號(hào)的用法,可避免因符號(hào)引起的程序錯(cuò)誤,是C#程序設(shè)計(jì)人員有必要掌握的,需要的朋友可以參考下2014-08-08
基于StreamRead和StreamWriter的使用(實(shí)例講解)
下面小編就為大家分享一篇基于StreamRead和StreamWriter的使用實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

