SBButton






3.18/5 (15投票s)
一个完全可定制的 .NET 2.0 按钮控件。
引言
SBButton 控件是我正在开发的一组控件(Sysbytes Controls)中的一个按钮控件,用于我正在编写的一个应用程序。这个按钮控件几乎可以按照用户喜欢的任何方式进行自定义。您可以为该控件的不同状态设置不同的样式,例如:DefaultStyle
、MouseOverStyle
、MouseDownStyle
和 DisabledStyle
。
工作原理
该控件继承自 Control
类和 IButtonControl
接口,并使用 OnPaint
事件使用 GDI+ 绘制控件。该控件使用一些与 .NET 提供的 Button
控件不同的属性。以下是这些属性:
DefaultStyle(默认样式)
MouseOverStyle(鼠标悬停样式)
MouseDownStyle(鼠标按下样式)
DisabledStyle(禁用样式)
RoundedCorners(圆角)
ShowFocusCue(显示焦点提示)
Image
ImageAlignment(图像对齐方式)
FocusCueColor(焦点提示颜色)
属性 DefaultStyle
、MouseOverStyle
、MouseDownStyle
和 DisabledStyle
均源自一个名为 SBButtonAppearance
的类,并且所有这些属性都具有一些共同的子属性。它们是:
BackColor1(背景色1)
BackColor2(背景色2)
HighLightColor(高亮颜色)
GlowColor(发光颜色)
InnerBorderColor(内边框颜色)
OuterBorderColor(外边框颜色)
TextColor
FillMode(填充模式)
字体
HighLightOpacity1(高亮透明度1)
HighLightOpacity2(高亮透明度2)
GlowOpacity(发光透明度)
InnerBorderOpacity(内边框透明度)
源代码
SBButtonAppearanceClass
的源代码如下:
[Serializable()]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class SBButtonAppearance
{
public event EventHandler<EventArgs> SBButtonAppearanceChanged;
private Color _backColor1 = SystemColors.ButtonFace;
public Color BackColor1
{
get { return _backColor1; }
set
{
_backColor1 = value;
AppearanceChanged();
}
}
private Color _backColor2 = SystemColors.ButtonFace;
public Color BackColor2
{
get { return _backColor2; }
set
{
_backColor2 = value;
AppearanceChanged();
}
}
private Color _outerBorderColor = SystemColors.ControlDarkDark;
public Color OuterBorderColor
{
get { return _outerBorderColor; }
set
{
_outerBorderColor = value;
AppearanceChanged();
}
}
private Color _innerBorderColor = SystemColors.ControlLightLight;
public Color InnerBorderColor
{
get { return _innerBorderColor; }
set
{
_innerBorderColor = value;
AppearanceChanged();
}
}
private Color _glowColor = SystemColors.ControlLightLight;
public Color GlowColor
{
get { return _glowColor; }
set
{
_glowColor = value;
AppearanceChanged();
}
}
private Color _highLightColor = SystemColors.ControlLightLight;
public Color HighLightColor
{
get { return _highLightColor; }
set
{
_highLightColor = value;
AppearanceChanged();
}
}
private Color _textColor = SystemColors.ControlText;
public Color TextColor
{
get { return _textColor; }
set
{
_textColor = value;
AppearanceChanged();
}
}
private Font _font = SystemFonts.DefaultFont;
public Font Font
{
get { return _font; }
set
{
_font = value;
AppearanceChanged();
}
}
private LinearGradientMode _fillMode = LinearGradientMode.Horizontal;
public LinearGradientMode FillMode
{
get { return _fillMode; }
set
{
_fillMode = value;
AppearanceChanged();
}
}
private int _innerBorderOpacity = 200;
public int InnerBorderOpacity
{
get { return _innerBorderOpacity; }
set
{
if (value > 255) value = 255;
if (value < 0) value = 0;
_innerBorderOpacity = value;
AppearanceChanged();
}
}
private int _highLightOpacity1 = 200;
public int HightLightOpacity1
{
get { return _highLightOpacity1; }
set
{
if (value > 255) value = 255;
if (value < 0) value = 0;
_highLightOpacity1 = value;
AppearanceChanged();
}
}
private int _highLightOpacity2 = 150;
public int HightLightOpacity2
{
get { return _highLightOpacity2; }
set
{
if (value > 255) value = 255;
if (value < 0) value = 0;
_highLightOpacity2 = value;
AppearanceChanged();
}
}
private int _glowOpacity = 120;
public int GlowOpacity
{
get { return _glowOpacity; }
set
{
if (value > 255) value = 255;
if (value < 0) value = 0;
_glowOpacity = value;
AppearanceChanged();
}
}
public override string ToString()
{
return null;
}
private void AppearanceChanged()
{
EventHandler<EventArgs> temp = SBButtonAppearanceChanged;
if (temp != null)
temp(this, new EventArgs());
}
}
绘制按钮的代码
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.TextRenderingHint =
System.Drawing.Text.TextRenderingHint.SystemDefault;
if(!isMouseIn && !isMouseDown && this.Enabled)
this.DrawDefault(e);
if (isMouseIn && !isMouseDown && this.Enabled)
this.DrawMouseOver(e);
if (isMouseIn && isMouseDown && this.Enabled)
this.DrawMouseDown(e);
if (!isMouseIn && isMouseDown && this.Enabled)
this.DrawMouseDown(e);
if (!this.Enabled)
this.DrawDisabled(e);
if (this.Focused && this.ShowFocusCue && this.Enabled)
ControlPaint.DrawBorder(e.Graphics, new Rectangle(
2, 2, this.Width - 4, this.Height - 4), this.FocusCueColor,
ButtonBorderStyle.Dashed);
}
private void DrawDefault(PaintEventArgs e)
{
LinearGradientBrush brBackground = new LinearGradientBrush(
this.ClientRectangle, this.DefaultStyle.BackColor1,
this.DefaultStyle.BackColor2, this.DefaultStyle.FillMode);
LinearGradientBrush brHighlight = new LinearGradientBrush(new Rectangle(
2, 2, this.Width - 5, this.Height / 2),
Color.FromArgb(this.DefaultStyle.HightLightOpacity1,
this.DefaultStyle.HighLightColor),
Color.FromArgb(this.DefaultStyle.HightLightOpacity2,
this.DefaultStyle.HighLightColor), LinearGradientMode.Vertical);
LinearGradientBrush brGlow = new LinearGradientBrush(new Rectangle(
0, this.Height - this.Height / 4 - 1, this.Width - 1, this.Height / 4),
Color.Transparent, Color.FromArgb(this.DefaultStyle.GlowOpacity,
this.DefaultStyle.GlowColor), LinearGradientMode.Vertical);
Pen pnOuterBorder = new Pen(this.DefaultStyle.OuterBorderColor, 1);
Pen pnInnerBorder = new Pen(Color.FromArgb(DefaultStyle.InnerBorderOpacity,
this.DefaultStyle.InnerBorderColor));
GraphicsPath gpBackground = Common.RoundedRect(new Rectangle(
0, 0, this.Width - 1, this.Height - 1), 3);
GraphicsPath gpGlow = Common.RoundedRect(new Rectangle(
1, this.Height - this.Height / 4, this.Width - 3, this.Height / 4), 1,1,3,3);
GraphicsPath gpHighlight = Common.RoundedRect(new Rectangle(
2, 2, this.Width - 5, this.Height / 2 - 1), 3, 3, 1, 1);
GraphicsPath gpOuterBorder = Common.RoundedRect(new Rectangle(
0, 0, this.Width - 1, this.Height - 1), 3);
GraphicsPath gpInnerBorder = Common.RoundedRect(new Rectangle(
1, 1, this.Width - 3, this.Height - 3), 3);
Rectangle rectBackground = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
Rectangle rectGlow = new Rectangle(1, this.Height - this.Height / 4,
this.Width - 3, this.Height / 4);
Rectangle rectHighlight = new Rectangle(2, 2, this.Width - 5, this.Height / 2 - 1);
Rectangle rectOuterBorder = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
Rectangle rectInnerBorder = new Rectangle(1, 1, this.Width - 3, this.Height - 3);
Size textSize = TextRenderer.MeasureText(this.Text, this.DefaultStyle.Font);
Point textPos = new Point(this.Width / 2 - textSize.Width / 2,
this.Height / 2 - textSize.Height / 2);
Point imagePos = new Point();
switch (this.ImageAlignment)
{
case Alignment.Right:
if (this.Image != null)
{
textPos = new Point(5, this.Height / 2 - textSize.Height / 2);
imagePos = new Point(this.Width - this.Image.Width - 5,
this.Height / 2 - this.Image.Size.Height / 2);
}
break;
case Alignment.Left:
if (this.Image != null)
{
textPos = new Point(this.Width - textSize.Width - 5,
this.Height / 2 - textSize.Height / 2);
imagePos = new Point(5, this.Height / 2 - this.Image.Size.Height / 2);
}
break;
}
if (this.RoundedCorners)
{
e.Graphics.FillPath(brBackground, gpBackground);
e.Graphics.FillPath(brGlow, gpGlow);
e.Graphics.FillPath(brHighlight, gpHighlight);
e.Graphics.DrawPath(pnOuterBorder, gpOuterBorder);
e.Graphics.DrawPath(pnInnerBorder, gpInnerBorder);
}
else
{
e.Graphics.FillRectangle(brBackground, rectBackground);
e.Graphics.FillRectangle(brGlow, rectGlow);
e.Graphics.FillRectangle(brHighlight, rectHighlight);
e.Graphics.DrawRectangle(pnOuterBorder, rectOuterBorder);
e.Graphics.DrawRectangle(pnInnerBorder, rectInnerBorder);
}
if (this.Image != null)
e.Graphics.DrawImage(this.Image, imagePos.X, imagePos.Y,
this.Image.Width, this.Image.Height);
TextRenderer.DrawText(e.Graphics, this.Text, this.DefaultStyle.Font,
textPos, this.DefaultStyle.TextColor);
}
方法 DrawMouseOver
、DrawMouseDown
和 DrawDisabled
与 DrawDefault
相同,只是使用的颜色和透明度值不同。您可能注意到此方法调用了一个函数 Common.RoundedRect
。此函数将返回一个带有圆角的矩形,作为 GraphicsPath
。
以下是此函数的代码:
public static System.Drawing.Drawing2D.GraphicsPath RoundedRect(
System.Drawing.Rectangle baseRect, int topLeftRadius,
int topRightRadius, int bottomLeftRadius, int bottomRightRadius)
{
int topLeftDiameter = topLeftRadius * 2;
int topRightDiameter = topRightRadius * 2;
int bottomLeftDiameter = bottomLeftRadius * 2;
int bottomRightDiameter = bottomRightRadius * 2;
System.Drawing.Drawing2D.GraphicsPath gp =
new System.Drawing.Drawing2D.GraphicsPath();
System.Drawing.Rectangle rectTopLeft = new System.Drawing.Rectangle(
baseRect.Left, baseRect.Top, topLeftDiameter, topLeftDiameter);
System.Drawing.Rectangle rectTopRight = new System.Drawing.Rectangle(
baseRect.Right - topRightDiameter, baseRect.Top, topRightDiameter,
topRightDiameter);
System.Drawing.Rectangle rectBottomLeft = new System.Drawing.Rectangle(
baseRect.Left, baseRect.Bottom - bottomLeftDiameter, bottomLeftDiameter,
bottomLeftDiameter);
System.Drawing.Rectangle rectBottomRight = new System.Drawing.Rectangle(
baseRect.Right - bottomRightDiameter, baseRect.Bottom - bottomRightDiameter,
bottomRightDiameter, bottomRightDiameter);
gp.AddArc(rectTopLeft, 180, 90);
gp.AddArc(rectTopRight, 270, 90);
gp.AddArc(rectBottomRight, 0, 90);
gp.AddArc(rectBottomLeft, 90, 90);
gp.CloseFigure();
return gp;
}
public static System.Drawing.Drawing2D.GraphicsPath RoundedRect(
System.Drawing.Rectangle baseRect, int cornerRadius)
{
int diameter = cornerRadius * 2;
System.Drawing.Drawing2D.GraphicsPath gp =
new System.Drawing.Drawing2D.GraphicsPath();
System.Drawing.Rectangle rectTopLeft = new System.Drawing.Rectangle(
baseRect.Left, baseRect.Top, diameter, diameter);
System.Drawing.Rectangle rectTopRight = new System.Drawing.Rectangle(
baseRect.Right - diameter, baseRect.Top, diameter, diameter);
System.Drawing.Rectangle rectBottomLeft = new System.Drawing.Rectangle(
baseRect.Left, baseRect.Bottom - diameter, diameter, diameter);
System.Drawing.Rectangle rectBottomRight = new System.Drawing.Rectangle(
baseRect.Right - diameter, baseRect.Bottom - diameter, diameter, diameter);
gp.AddArc(rectTopLeft, 180, 90);
gp.AddArc(rectTopRight, 270, 90);
gp.AddArc(rectBottomRight, 0, 90);
gp.AddArc(rectBottomLeft, 90, 90);
gp.CloseFigure();
return gp;
}
关注点
此控件支持图像,并且图像只能对齐到左侧或右侧。如果没有图像,文本将始终对齐到控件的中心。您可以很容易地通过编辑方法 DrawDefault
、DrawMouseOver
、DrawMouseDown
和 DrawDisabled
来修改这些行为。