寫了一個繪制圓角Button的工具類:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace WinformLx.Class
{
enum buttonStyle
{
/// <summary>
/// 正常為選中按鈕
/// </summary>
ButtonNormal,
/// <summary>
/// 獲得焦點的按鈕
/// </summary>
ButtonFocuse,
/// <summary>
/// 鼠標經過樣式
/// </summary>
ButtonMouseOver,
/// <summary>
/// 獲得焦點並鼠標經過
/// </summary>
ButtonFocuseAndMouseOver
}
/// <summary>
/// 自定義GDI工具,繪制按鈕
/// </summary>
class Util_GDI
{
/// <summary>
/// 繪制圓形按鈕(用法同矩形按鈕)
/// </summary>
/// <param name="text"></param>
/// <param name="g"></param>
/// <param name="Location"></param>
/// <param name="r"></param>
/// <param name="btnStyle"></param>
public static void DrawCircleButton(string text, Graphics g, Point Location, int r, buttonStyle btnStyle)
{
Graphics Gcircle = g;
Rectangle rect = new Rectangle(Location.X, Location.Y, r, r);
Pen p = new Pen(new SolidBrush(Color.Black));
Gcircle.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
Gcircle.DrawEllipse(p, rect);
if (btnStyle == buttonStyle.ButtonFocuse)
{
Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#338FCC")), rect);
}
else if (btnStyle == buttonStyle.ButtonMouseOver)
{
Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#EAC100")), rect);
}
else if (btnStyle == buttonStyle.ButtonFocuseAndMouseOver)
{
Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#EAC100")), rect);
}
p.DashStyle = DashStyle.Dash;
if (btnStyle != buttonStyle.ButtonNormal)
{
Gcircle.DrawEllipse(p, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));//虛線框
}
Gcircle.FillEllipse(new SolidBrush(Color.WhiteSmoke), new Rectangle(rect.X + 3, rect.Y + 3, rect.Width - 6, rect.Height - 6));
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
Gcircle.DrawString(text, new Font(new FontFamily("宋體"), 10), new SolidBrush(Color.Black), rect, sf);
p.Dispose();
}
/// <summary>
/// 繪制圓角按鈕
/// </summary>
/// <param name="Text">要繪制的文字</param>
/// <param name="g">Graphics 對象</param>
/// <param name="rect">要填充的矩形</param>
/// <param name="btnStyle"></param>
public static void DrawRoundButton(string Text, Graphics g, Rectangle rect,buttonStyle btnStyle)
{
//g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.AntiAlias;//消除鋸齒
Rectangle rectangle = rect;
Brush b = b = new SolidBrush(Color.Black);
if (btnStyle == buttonStyle.ButtonFocuse)
{
b = new SolidBrush(ColorTranslator.FromHtml("#338FCC"));
}
else if (btnStyle == buttonStyle.ButtonMouseOver)
{
b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
}
else if (btnStyle == buttonStyle.ButtonFocuseAndMouseOver)
{
b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
}
g.DrawPath(new Pen(b),GetRoundRectangle(rectangle, 2));
rectangle = new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4);
Pen p=new Pen(Color.Black,0.5f);
p.DashStyle = DashStyle.Dash;
if (btnStyle == buttonStyle.ButtonFocuse || btnStyle == buttonStyle.ButtonFocuseAndMouseOver)
{
g.DrawRectangle(p,rectangle);//虛線框
}
g.FillRectangle(new SolidBrush(Color.WhiteSmoke),rectangle);//白色背景
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(Text, new Font("宋體", 10), new SolidBrush(Color.Black), rectangle, sf);
p.Dispose();
b.Dispose();
g.SmoothingMode = SmoothingMode.Default;
}
/// <summary>
/// 根據普通矩形得到圓角矩形的路徑
/// </summary>
/// <param name="rectangle">原始矩形</param>
/// <param name="r">半徑</param>
/// <returns>圖形路徑</returns>
private static GraphicsPath GetRoundRectangle(Rectangle rectangle, int r)
{
int l = 2 * r;
// 把圓角矩形分成八段直線、弧的組合,依次加到路徑中
GraphicsPath gp = new GraphicsPath();
gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);
gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);
gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);
gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
return gp;
}
}
}
新建一個cs命名為MyButton,繼承Button類,重寫Button類的Paint方法:
using System;
using System.Windows;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using WinformLx.Class; //引用之前工具類的命名空間
namespace WinformLx.UserControls
{
public class MyButton : System.Windows.Forms.Button
{
private bool mouseover = false;//鼠標經過
public MyButton()
{
this.Cursor = System.Windows.Forms.Cursors.Hand;
}
protected override void OnPaint(PaintEventArgs e)
{
//在這里用自己的方法來繪制Button的外觀(其實也就是幾個框框)
Graphics g = e.Graphics;
g.Clear(this.BackColor);
Rectangle rect = e.ClipRectangle;
rect = new Rectangle(rect.X,rect.Y,rect.Width-1,rect.Height-2);
//g.ReleaseHdc();
if (mouseover)
{
if (Focused)
{
Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonFocuseAndMouseOver);
return;
}
Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonMouseOver);
return;
}
if (Focused)
{
Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonFocuse);
return;
}
Util_GDI.DrawRoundButton(this.Text, g, rect, buttonStyle.ButtonNormal);
}
protected override void OnMouseEnter(EventArgs e)
{
mouseover = true;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
mouseover = false;
base.OnMouseLeave(e);
}
}
}
上面的工作完成以后會在vs的工具欄發現剛剛自己寫的那個MyButton
新建一個窗口,拖上去就可以了。
和windows繪制的button明顯不一樣吧,因為只是重寫了繪制方法,改變了一下外觀,事件那些還是一樣可以用的。