做WinForm开发的朋友,应该都有这种感觉:vs自带的控件倒是不少,但美观的却很少 ——于是网上就有一些开源、收费或免费的不错的控件,像皮肤等控件库DotNetBar、饼状图控件pieChart(此控件的使用,可查看之前的一篇文章:WinForm"立体饼状图实现(附源码示例)" 之配餐系统的开发)....,(在之前的几篇介绍配餐系统开发的文章里,我主要是对一些功能的说明)而此文要跟大家分享的是"不错的Vista风格水晶按钮"控件的使用(界面美观性和用户体验的增强)。好了,直接切入正题,先看下此控件的运行效果:
此按钮控件有以下几点值得说明一下:
1.CornerRadius: ——此属性用来设置按钮两端的形状(椭圆或普通),属性值为数字,0:即普通按钮,>0的值则按钮的椭圆‘弯曲度’更大, 为20时即为上图中 绿色按钮,当值>20后效果就不太好,具体可下载demo后自行查看。
2.按钮的BaseColor和ButtonColor同时设置,其效果类似于 渐变。
此按钮控件 关键代码如下:
/// <summary>
/// Draws the outer border for the control
/// using the ButtonColor property.
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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>
/// Draws the inner border for the control
/// using the HighlightColor property.
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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>
/// Draws the background for the control
/// using the background image and the
/// BaseColor.
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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>
/// Draws the Highlight over the top of the
/// control using the HightlightColor.
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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>
/// Draws the glow for the button when the
/// mouse is inside the client area using
/// the GlowColor property.
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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>
/// Draws the text for the button.
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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>
/// Draws the image for the button
/// </summary>
/// <param name="g">The graphics object used in the paint event.</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);
}
}