C# 自定义按钮控件库

流程就不说了,和之前的帖子中说的一样。

首先来看看变量

       private bool calledbykey = false;
private State mButtonState = State.None;
private Timer mFadeIn = new Timer(); //时间控件用来反映鼠标在进入按钮后
private Timer mFadeOut = new Timer();//这个是反映鼠标在离开按钮后的
private int mGlowAlpha = 0;//反映按钮中的颜色亮度的
enum State {None, Hover, Pressed};//按钮的状态
public enum Style
{
Default,
Flat
};

  

 基本框架

        public Button()
{
InitializeComponent();

this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
mFadeIn.Interval
= 30;
mFadeOut.Interval
= 30;
}

  

private void InitializeComponent()
{
//
// VistaButton
//
this.Name = "VistaButton";
this.Size = new System.Drawing.Size(100, 32);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.VistaButton_Paint);//绘制
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyUp);//释放按键
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyDown);//首次按下时
this.MouseEnter += new System.EventHandler(this.VistaButton_MouseEnter);//鼠标在内
this.MouseLeave += new System.EventHandler(this.VistaButton_MouseLeave);//鼠标离开
this.MouseUp +=new MouseEventHandler(VistaButton_MouseUp);//鼠标在按钮的空间里放开
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.VistaButton_MouseDown);//鼠标在按钮的空间里按下
this.GotFocus +=new EventHandler(VistaButton_MouseEnter);//聚焦
this.LostFocus +=new EventHandler(VistaButton_MouseLeave);//失去焦点
this.mFadeIn.Tick += new EventHandler(mFadeIn_Tick);//时间控件

this.mFadeOut.Tick += new EventHandler(mFadeOut_Tick);//时间控件
this.Resize +=new EventHandler(VistaButton_Resize);//调整大小
}

  下来再看看要定义的属性值有哪些

            private string mText; //按钮上显示的文字
private Color mForeColor = Color.White;
private ContentAlignment mTextAlign = ContentAlignment.MiddleCenter;//居中显示 默认
private Image mImage; //显示图片
private Size mImageSize = new Size(24, 24);//图片的尺寸
private Style mButtonStyle = Style.Default;
private int mCornerRadius = 8; //贝塞尔的值,用来控制按钮的圆润程度
private Color mHighlightColor = Color.White;//按钮的增亮部分
private Color mButtonColor = Color.Black;//按钮的底色部分
private Color mGlowColor = Color.FromArgb(141, 189, 255); //当鼠标悬停在按钮范围内时,变色的部分颜色
private Image mBackImage;//背景图片
private Color mBaseColor = Color.Black;//基础颜色

 各个属性值在属性页中的显示

        [Category("Text"),Description("按钮的显示字样")]
public string ButtonText //按钮上显示的字
{
get { return mText; }
set { mText = value; this.Invalidate(); }
}

[Category(
"Text"), //分类
Browsable(true),//是否显示
DefaultValue(typeof(Color),"White"),//初始值
Description("字样的颜色")]//属性描述
public override Color ForeColor //修改颜色属性
{
get { return mForeColor; }
set { mForeColor = value; this.Invalidate(); }
}
[Category(
"Text"), DefaultValue(typeof(ContentAlignment),"MiddleCenter"),Description("按钮的显示文字 " + "在按钮的显示")]
public ContentAlignment TextAlign
{
get { return mTextAlign; }
set { mTextAlign = value; this.Invalidate(); }
}

[Category(
"Image"), DefaultValue(null),Description("图片 " +"帮助用户能够" + "清晰看到文字")]
public Image Image
{
get { return mImage; }
set { mImage = value; this.Invalidate(); }
}

private ContentAlignment mImageAlign = ContentAlignment.MiddleLeft;
[Category(
"Image"), DefaultValue(typeof(ContentAlignment),"MiddleLeft"),Description("图标在按钮中关联的位置")]
public ContentAlignment ImageAlign
{
get { return mImageAlign; }
set { mImageAlign = value; this.Invalidate(); }
}
[Category(
"Image"), DefaultValue(typeof(Size),"24, 24"),Description("图片显示在按钮上的尺寸,默认是 24x24.")]
public Size ImageSize
{
get { return mImageSize; }
set { mImageSize = value; this.Invalidate(); }
}
[Category(
"Appearance"), DefaultValue(typeof(Style),"Default"),Description("当鼠标离开按钮时,设置是否显示成深色")]
public Style ButtonStyle
{
get { return mButtonStyle; }
set { mButtonStyle = value; this.Invalidate(); }
}
[Category(
"Appearance"), DefaultValue(8),Description("控制按钮棱角圆润程度的")]
public int CornerRadius
{
get { return mCornerRadius; }
set { mCornerRadius = value; this.Invalidate(); }
}
[Category(
"Appearance"), DefaultValue(typeof(Color), "White"),Description("绘制按钮颜色时的增亮部分")]
public Color HighlightColor
{
get { return mHighlightColor; }
set { mHighlightColor = value; this.Invalidate(); }
}
[Category(
"Appearance"), DefaultValue(typeof(Color), "Black"), Description("按钮在未被使用时的底色部分")]
public Color ButtonColor
{
get { return mButtonColor; }
set { mButtonColor = value; this.Invalidate(); }
}
[Category(
"Appearance"), DefaultValue(typeof(Color), "141,189,255"), Description("鼠标在悬停按钮的部分,变色的部分")]
public Color GlowColor
{
get { return mGlowColor; }
set { mGlowColor = value; this.Invalidate(); }
}

[Category(
"Appearance"), DefaultValue(null), Description("背景图片")]
public Image BackImage
{
get { return mBackImage; }
set { mBackImage = value; this.Invalidate(); }
}
[Category(
"Appearance"), DefaultValue(typeof(Color), "Black"), Description("按键在按下时,显示这个颜色来过渡")]
public Color BaseColor
{
get { return mBaseColor; }
set { mBaseColor = value; this.Invalidate(); }
}

  属性的定义就这么多,下来就要看看按钮是怎么画出来的,以及尺寸变化的一些事宜

private void VistaButton_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode
= SmoothingMode.AntiAlias;
e.Graphics.InterpolationMode
= InterpolationMode.HighQualityBicubic;
DrawBackground(e.Graphics);//绘制背景
DrawHighlight(e.Graphics);//绘制高亮
DrawImage(e.Graphics);//绘制图标
DrawText(e.Graphics);//绘制显示字
DrawGlow(e.Graphics);//当鼠标进入按钮后显示的颜色变化
DrawOuterStroke(e.Graphics);//绘制按钮底层
DrawInnerStroke(e.Graphics);//绘制按钮上涂层
}

  下面就一个个的看

            private GraphicsPath RoundRect(RectangleF r, float r1, float r2, float r3, float r4)//通过贝赛尔曲线画出带有弧度的按钮,绘制轮廓
{
float x = r.X, y = r.Y, w = r.Width, h = r.Height;
GraphicsPath rr
= new GraphicsPath();
rr.AddBezier(x, y
+ r1, x, y, x + r1, y, x + r1, y);
rr.AddLine(x
+ r1, y, x + w - r2, y);
rr.AddBezier(x
+ w - r2, y, x + w, y, x + w, y + r2, x + w, y + r2);
rr.AddLine(x
+ w, y + r2, x + w, y + h - r3);
rr.AddBezier(x
+ w, y + h - r3, x + w, y + h, x + w - r3, y + h, x + w - r3, y + h);
rr.AddLine(x
+ w - r3, y + h, x + r4, y + h);
rr.AddBezier(x
+ r4, y + h, x, y + h, x, y + h - r4, x, y + h - r4);
rr.AddLine(x, y
+ h - r4, x, y + r1);
return rr;
}
private StringFormat StringFormatAlignment(ContentAlignment textalign)//文字在按钮中的信息,位置
{
StringFormat sf
= new StringFormat();
switch (textalign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.TopCenter:
case ContentAlignment.TopRight:
sf.LineAlignment
= StringAlignment.Near;
break;
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleRight:
sf.LineAlignment
= StringAlignment.Center;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
sf.LineAlignment
= StringAlignment.Far;
break;
}
switch (textalign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.MiddleLeft:
case ContentAlignment.BottomLeft:
sf.Alignment
= StringAlignment.Near;
break;
case ContentAlignment.TopCenter:
case ContentAlignment.MiddleCenter:
case ContentAlignment.BottomCenter:
sf.Alignment
= StringAlignment.Center;
break;
case ContentAlignment.TopRight:
case ContentAlignment.MiddleRight:
case ContentAlignment.BottomRight:
sf.Alignment
= StringAlignment.Far;
break;
}
return sf;
}
private void DrawOuterStroke(Graphics g) //绘制按钮基底的颜色部分
{
if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None){return;}
Rectangle r
= this.ClientRectangle;
r.Width
-= 1; r.Height -= 1;
using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
{
using (Pen p = new Pen(this.ButtonColor))
{
g.DrawPath(p, rr);
}
}
}
private void DrawInnerStroke(Graphics g)//绘制按钮上面涂层部分
{
if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None){return;}
Rectangle r
= this.ClientRectangle;
r.X
++; r.Y++;
r.Width
-= 3; r.Height -= 3;
using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
{
using (Pen p = new Pen(this.HighlightColor))
{
g.DrawPath(p, rr);
}
}
}
private void DrawBackground(Graphics g)//绘制按钮的背景色
{
if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None){return;}
int alpha = (mButtonState == State.Pressed) ? 204 : 127;
Rectangle r
= this.ClientRectangle;
r.Width
--; r.Height--;
using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
{
using (SolidBrush sb = new SolidBrush(this.BaseColor))
{
g.FillPath(sb, rr);
}
SetClip(g);
if (this.BackImage != null){g.DrawImage(this.BackImage, this.ClientRectangle);}
g.ResetClip();
using (SolidBrush sb = new SolidBrush(Color.FromArgb(alpha, this.ButtonColor)))
{
g.FillPath(sb, rr);
}
}
}
private void DrawHighlight(Graphics g)
{
if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None){return;}
int alpha = (mButtonState == State.Pressed) ? 60 : 150;
Rectangle rect
= new Rectangle(0, 0, this.Width, this.Height / 2);
using (GraphicsPath r = RoundRect(rect, CornerRadius, CornerRadius, 0, 0))
{
using (LinearGradientBrush lg = new LinearGradientBrush(r.GetBounds(),
Color.FromArgb(alpha,
this.HighlightColor),
Color.FromArgb(alpha
/ 3, this.HighlightColor),
LinearGradientMode.Vertical))
//绘制出玻璃的光泽感
{
g.FillPath(lg, r);
}
}
}
private void DrawGlow(Graphics g) //绘制鼠标悬停在按钮上时,按钮变色的部分
{
if (this.mButtonState == State.Pressed){return;}
SetClip(g);
using (GraphicsPath glow = new GraphicsPath())
{
glow.AddEllipse(
-5,this.Height / 2 - 10, this.Width + 11, this.Height + 11);
using (PathGradientBrush gl = new PathGradientBrush(glow))
{
gl.CenterColor
= Color.FromArgb(mGlowAlpha, this.GlowColor);
gl.SurroundColors
= new Color[] {Color.FromArgb(0, this.GlowColor)};
g.FillPath(gl, glow);
}
}
g.ResetClip();
}
private void DrawText(Graphics g) //按钮的字样
{
StringFormat sf
= StringFormatAlignment(this.TextAlign);
Rectangle r
= new Rectangle(8,8,this.Width - 17,this.Height - 17);
g.DrawString(
this.ButtonText,this.Font,new SolidBrush(this.ForeColor),r,sf);
}
private void DrawImage(Graphics g)//图标的绘制
{
if (this.Image == null) {return;}
Rectangle r
= new Rectangle(8,8,this.ImageSize.Width,this.ImageSize.Height);
switch (this.ImageAlign)
{
case ContentAlignment.TopCenter:
r
= new Rectangle(this.Width / 2 - this.ImageSize.Width / 2,8,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.TopRight:
r
= new Rectangle(this.Width - 8 - this.ImageSize.Width,8,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.MiddleLeft:
r
= new Rectangle(8,this.Height / 2 - this.ImageSize.Height / 2,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.MiddleCenter:
r
= new Rectangle(this.Width / 2 - this.ImageSize.Width / 2,this.Height / 2 - this.ImageSize.Height / 2,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.MiddleRight:
r
= new Rectangle(this.Width - 8 - this.ImageSize.Width,this.Height / 2 - this.ImageSize.Height / 2,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.BottomLeft:
r
= new Rectangle(8,this.Height - 8 - this.ImageSize.Height,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.BottomCenter:
r
= new Rectangle(this.Width / 2 - this.ImageSize.Width / 2,this.Height - 8 - this.ImageSize.Height,this.ImageSize.Width,this.ImageSize.Height);
break;
case ContentAlignment.BottomRight:
r
= new Rectangle(this.Width - 8 - this.ImageSize.Width,this.Height - 8 - this.ImageSize.Height,this.ImageSize.Width,this.ImageSize.Height);
break;
}
g.DrawImage(
this.Image,r);
}
private void SetClip(Graphics g)
{
Rectangle r
= this.ClientRectangle;
r.X
++; r.Y++; r.Width-=3; r.Height-=3;
using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
{
g.SetClip(rr);

}
}

  还有个常用的事件就是Resize

private void VistaButton_Resize(object sender, EventArgs e)
{
Rectangle r
= this.ClientRectangle;
r.X
-= 1; r.Y -= 1;
r.Width
+= 2; r.Height += 2;
using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))
{
this.Region = new Region(rr);
}
}

  

用的多的一般就是鼠标在按钮上的停留、离开、点击等等,我们一个个看

private void VistaButton_MouseEnter(object sender, EventArgs e)//鼠标进入按钮
{
mButtonState
= State.Hover;//状态悬停
mFadeOut.Stop();
mFadeIn.Start();
}
//mGlowAlpha是亮度值
private void VistaButton_MouseLeave(object sender, EventArgs e)//鼠标离开按钮
{
mButtonState
= State.None; //未被使用
if (this.mButtonStyle == Style.Flat) { mGlowAlpha = 0; }
mFadeIn.Stop();
mFadeOut.Start();
}
private void mFadeIn_Tick(object sender, EventArgs e)
{
if (this.ButtonStyle == Style.Flat) {mGlowAlpha = 0;}
if (mGlowAlpha + 30 >= 255)
{
mGlowAlpha
= 255;
mFadeIn.Stop();
}
else
{
mGlowAlpha
+= 30;
}
this.Invalidate();
}

private void mFadeOut_Tick(object sender, EventArgs e)
{
if (this.ButtonStyle == Style.Flat) {mGlowAlpha = 0;}
if (mGlowAlpha - 30 <= 0)
{
mGlowAlpha
= 0;
mFadeOut.Stop();
}
else
{
mGlowAlpha
-= 30;
}
this.Invalidate();
}

private void VistaButton_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
MouseEventArgs m
= new MouseEventArgs(MouseButtons.Left,0,0,0,0);
VistaButton_MouseDown(sender, m);
}
}

private void VistaButton_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
MouseEventArgs m
= new MouseEventArgs(MouseButtons.Left,0,0,0,0);
calledbykey
= true;
VistaButton_MouseUp(sender, m);
}
}

private void VistaButton_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mButtonState
= State.Hover;
mFadeIn.Stop();
mFadeOut.Stop();
this.Invalidate();
if (calledbykey == true) {this.OnClick(EventArgs.Empty); calledbykey = false;}
}
}
private void VistaButton_MouseDown(object sender, MouseEventArgs e)//鼠标按下
{
if (e.Button == MouseButtons.Left)
{
mButtonState
= State.Pressed;
if (this.mButtonStyle != Style.Flat) { mGlowAlpha = 255; }
mFadeIn.Stop();
mFadeOut.Stop();
this.Invalidate();
}
}

  

posted @ 2011-09-01 15:31  Tammie-锴  阅读(3453)  评论(0编辑  收藏  举报