C#自定义控件三Vista按钮
C#自定义控件三Vista按钮
效果图:
Vista和Win7操作系统的按钮非常华丽,用C#GDI+去实现也挺方便的,这个是参考网上源码修改过来的,个人觉得非常有学习价值。
第一步:添加用户控件,命名为myVistaButton
第二步:确定需要的属性,例如文字、背景颜色、图片等。
第三步:重写Paint事件,为了增强效果,还可以重写鼠标移入移出等事件。
贴出核心代码:
#region 方法
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;
}
/// <summary>
/// 绘制外部边框
/// </summary>
/// <param name="g"></param>
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);
}
}
}
/// <summary>
/// 绘制内部边框
/// </summary>
/// <param name="g"></param>
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);
}
}
}
/// <summary>
/// 绘制背景
/// </summary>
/// <param name="g"></param>
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);
}
}
}
/// <summary>
/// 绘制高亮颜色
/// </summary>
/// <param name="g"></param>
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);
}
}
}
/// <summary>
/// 绘制鼠标移入颜色
/// </summary>
/// <param name="g"></param>
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();
}
/// <summary>
/// 绘制文本
/// </summary>
/// <param name="g"></param>
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);
}
/// <summary>
/// 绘制图片
/// </summary>
/// <param name="g"></param>
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);
}
}
#endregion
重写Paint事件:
private void myVistaButton_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);
}