using ryControls.Skin;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ryControls
{
///
/// 控件的状态。
///
public enum ControlState
{
///
/// 正常
///
Normal,
///
/// 鼠标经过
///
Hover,
///
/// 鼠标按下
///
Pressed,
}
///
/// 鼠标的当前位置
///
public enum ButtonMousePosition
{
///
///
///
None,
///
///
///
Button,
///
///
///
Splitebutton,
}
///
/// 美化按钮
///
public class ButtonEx : Button
{
private Color _baseColor = Color.FromArgb(12, 125, 182);//基颜色
private Color _foreColor = Color.White;//字体颜色
private ControlState _controlState;//控件状态
private int _imageWidth = 16;
private RoundStyle _roundStyle = RoundStyle.All;//圆角
private int _radius = 8; //圆角半径
///
/// 普通按钮矩形位置
///
internal Rectangle ButtonRect
{
get
{
if (ShowSpliteButton)
{
return new Rectangle(0, 0, ClientRectangle.Width - SpliteButtonWidth, ClientRectangle.Height);
}
else
{
return new Rectangle(0,0,Width,Height);
}
}
}
///
///美化按钮
///
public ButtonEx() : base()
{
ForeColor = Color.White;
this.SetStyle(
ControlStyles.UserPaint | //控件自行绘制,而不使用操作系统的绘制
ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。
ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。
ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。
ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色
}
private int _spliteButtonWidth = 18;
///
/// 分割按钮的宽度
///
[DefaultValue(18)]
[Description("分割按钮的宽度")]
public int SpliteButtonWidth
{
get { return _spliteButtonWidth; }
set
{
if (_spliteButtonWidth != value)
{
_spliteButtonWidth = value;
base.Invalidate();
}
}
}
private bool _showSpliteButton = false;
///
/// 是否启用分割按钮
///
[DefaultValue(false)]
[Description("是否启用分割按钮")]
public bool ShowSpliteButton
{
get { return _showSpliteButton; }
set
{
if (_showSpliteButton != value)
{
_showSpliteButton = value;
base.Invalidate();
}
}
}
private bool _UseDefSkin = true;
///
///优先使用默认皮肤
///
[Description("优先使用默认皮肤")]
[DefaultValue(typeof(bool), "true")]
public bool UseDefSkin
{
get
{
return _UseDefSkin;
}
set
{
_UseDefSkin = value;
base.Invalidate();
}
}
///
///按钮基础背景色
///
[Description("按钮基础背景色")]
[DefaultValue(typeof(Color), "12, 125, 182")]
public Color BaseColor
{
get
{
if(SkinCommon.UseDefSkin && UseDefSkin)
{
return SkinCommon.ButtonSkin.BackColor;
}
return _baseColor;
}
set
{
_baseColor = value;
base.Invalidate();
}
}
///
///按钮字体颜色
///
[Description("按钮字体颜色")]
[DefaultValue(typeof(Color), "255, 255, 255")]
public new Color ForeColor
{
get
{
if (SkinCommon.UseDefSkin && UseDefSkin)
{
return SkinCommon.ButtonSkin.ForeColor;
}
return _foreColor;
}
set
{
_foreColor = value;
base.Invalidate();
}
}
///
///图片宽度,默认值为18px,最小12px
///
[Description("图片宽度,默认值为18px,最小12px")]
[DefaultValue(16)]//默认值为18px,最小12px
public int ImageWidth
{
get { return _imageWidth; }
set
{
if (value != _imageWidth)
{
_imageWidth = value < 12 ? 12 : value;
base.Invalidate();
}
}
}
///
///圆角的位置,默认全部都是圆角
///
[Description("圆角的位置,默认全部都是圆角")]
[DefaultValue(typeof(RoundStyle), "1")]//默认全部都是圆角
public RoundStyle RoundStyle
{
get { return _roundStyle; }
set
{
if (_roundStyle != value)
{
_roundStyle = value;
base.Invalidate();
}
}
}
///
///设置圆角半径
///
[Description("圆角半径")]
[DefaultValue(8)]//设置圆角半径,默认值为8,最小值为4px
public int Radius
{
get { return _radius; }
set
{
if (_radius != value)
{
_radius = value < 4 ? 4 : value;
base.Invalidate();
}
}
}
private bool _ColorGradient = false;
///
/// 背景色是否渐变
///
[DefaultValue(false)]
[Description("背景色是否渐变")]
public bool ColorGradient
{
get
{
if (SkinCommon.UseDefSkin && UseDefSkin)
{
return SkinCommon.ButtonSkin.ColorGradient;
}
return _ColorGradient;
}
set
{
if (value != _ColorGradient)
{
_ColorGradient = value;
base.Invalidate();
}
}
}
private int _imageHeight = 16;
///
/// 图片高度
///
[DefaultValue(16)]
[Description("图片高度")]
public int ImageHeight
{
get { return _imageHeight; }
set
{
if (value != _imageHeight)
{
_imageHeight = value < 12 ? 12 : value;
base.Invalidate();
}
}
}
private int _imageTextSpace = 2;
///
/// 图片与文字之间的间距
///
[DefaultValue(2)]
[Description("图片与文字之间的间距")]
public int ImageTextSpace
{
get { return _imageTextSpace; }
set
{
if (_imageTextSpace != value)
{
_imageTextSpace = value < 0 ? 0 : value;
base.Invalidate();
}
}
}
private bool _pressOffset = true;
///
/// 当鼠标按下时图片和文字是否产生偏移
///
[DefaultValue(true)]
[Description("当鼠标按下时图片和文字是否产生偏移")]
public bool PressOffset
{
get { return _pressOffset; }
set
{
_pressOffset = value;
}
}
internal ControlState ControlState //控件的状态
{
get { return _controlState; }
set
{
if (_controlState != value)
{
_controlState = value;
base.Invalidate();
}
}
}
///
/// 鼠标进入时
///
///
protected override void OnMouseEnter(EventArgs e)//鼠标进入时
{
base.OnMouseEnter(e);
ControlState = ControlState.Hover;//正常
}
///
/// 鼠标离开
///
///
protected override void OnMouseLeave(EventArgs e)//鼠标离开
{
base.OnMouseLeave(e);
ControlState = ControlState.Normal;//正常
}
///
/// 鼠标按下
///
///
protected override void OnMouseDown(MouseEventArgs e)//鼠标按下
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left && e.Clicks == 1)//鼠标左键且点击次数为1
{
ControlState = ControlState.Pressed;//按下的状态
}
}
///
/// 鼠标弹起
///
///
protected override void OnMouseUp(MouseEventArgs e)//鼠标弹起
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left && e.Clicks == 1)
{
if (ClientRectangle.Contains(e.Location))//控件区域包含鼠标的位置
{
ControlState = ControlState.Hover;
}
else
{
ControlState = ControlState.Normal;
}
}
}
private ButtonMousePosition _mousePosition;
///
/// 鼠标当前所在位置
///
internal ButtonMousePosition CurrentMousePosition
{
get { return _mousePosition; }
set
{
if (_mousePosition != value)
{
_mousePosition = value;
base.Invalidate();
}
}
}
///
/// 获取图像以及文字的位置
///
///
///
///
private void CalculateRect(
out Rectangle imageRect, out Rectangle textRect, Graphics g)
{
imageRect = Rectangle.Empty;
textRect = Rectangle.Empty;
SizeF textSize = g.MeasureString(Text, Font);
if (Image == null)
{
switch (TextAlign)
{
case ContentAlignment.BottomCenter:
textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.BottomLeft:
textRect = new Rectangle(2, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.BottomRight:
textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, Height - (int)textSize.Height - 3, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.MiddleCenter:
textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.MiddleLeft:
textRect = new Rectangle(2, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.MiddleRight:
textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, (Height - (int)textSize.Height) / 2, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.TopCenter:
textRect = new Rectangle((ButtonRect.Width - (int)textSize.Width) / 2, 2, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.TopLeft:
textRect = new Rectangle(2, 2, (int)textSize.Width, (int)textSize.Height);
break;
case ContentAlignment.TopRight:
textRect = new Rectangle(ButtonRect.Width - (int)textSize.Width - 3, 2, (int)textSize.Width, (int)textSize.Height);
break;
}
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button)
{
textRect.X += 1;
textRect.Y += 1;
}
if (RightToLeft == RightToLeft.Yes)
{
textRect.X = ButtonRect.Width - textRect.Right;
}
return;
}
if (this.Text == "")
{
switch (ImageAlign)
{
case ContentAlignment.BottomCenter:
imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, Height - ImageHeight - 3, ImageWidth, ImageHeight);
break;
case ContentAlignment.BottomLeft:
imageRect = new Rectangle(2, Height - ImageHeight - 3, ImageWidth, ImageHeight);
break;
case ContentAlignment.BottomRight:
imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, Height - ImageHeight - 3, ImageWidth, ImageHeight);
break;
case ContentAlignment.MiddleCenter:
imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight);
break;
case ContentAlignment.MiddleLeft:
imageRect = new Rectangle(2, (Height - ImageHeight) / 2, ImageWidth, ImageHeight);
break;
case ContentAlignment.MiddleRight:
imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, (Height - ImageHeight) / 2, ImageWidth, ImageHeight);
break;
case ContentAlignment.TopCenter:
imageRect = new Rectangle((ButtonRect.Width - ImageWidth) / 2, 2, ImageWidth, ImageHeight);
break;
case ContentAlignment.TopLeft:
imageRect = new Rectangle(2, 2, ImageWidth, ImageHeight);
break;
case ContentAlignment.TopRight:
imageRect = new Rectangle(ButtonRect.Width - ImageWidth - 3, 2, ImageWidth, ImageHeight);
break;
}
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button)
{
imageRect.X += 1;
imageRect.Y += 1;
}
if (RightToLeft == RightToLeft.Yes)
{
imageRect.X = ButtonRect.Width - imageRect.Right;
}
return;
}
switch (TextImageRelation)
{
case TextImageRelation.Overlay:
imageRect = new Rectangle(
(ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2,
(Height - ImageHeight) / 2,
ImageWidth,
ImageHeight);
textRect = new Rectangle(
imageRect.Right + ImageTextSpace,
(Height - (int)textSize.Height) / 2,
(int)textSize.Width,
(int)textSize.Height);
break;
case TextImageRelation.ImageAboveText:
imageRect = new Rectangle(
(ButtonRect.Width - ImageWidth) / 2,
(Height - ImageHeight - (int)textSize.Height - ImageTextSpace) / 2,
ImageWidth,
ImageHeight);
textRect = new Rectangle(
(ButtonRect.Width - (int)textSize.Width) / 2,
imageRect.Bottom + ImageTextSpace,
(int)textSize.Width,
(int)textSize.Height);
break;
case TextImageRelation.ImageBeforeText:
imageRect = new Rectangle(
(ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2,
(Height - ImageHeight) / 2,
ImageWidth,
ImageHeight);
textRect = new Rectangle(
imageRect.Right + ImageTextSpace,
(Height - (int)textSize.Height) / 2,
(int)textSize.Width,
(int)textSize.Height);
break;
case TextImageRelation.TextAboveImage:
textRect = new Rectangle(
(ButtonRect.Width - (int)textSize.Width) / 2,
(Height - (int)textSize.Height - ImageHeight - ImageTextSpace) / 2,
(int)textSize.Width,
(int)textSize.Height);
imageRect = new Rectangle(
(ButtonRect.Width - ImageWidth) / 2,
textRect.Bottom + ImageTextSpace,
ImageWidth,
ImageHeight);
break;
case TextImageRelation.TextBeforeImage:
textRect = new Rectangle(
(ButtonRect.Width - ImageWidth - (int)textSize.Width - ImageTextSpace) / 2,
(Height - (int)textSize.Height) / 2,
(int)textSize.Width,
(int)textSize.Height);
imageRect = new Rectangle(
textRect.Right + ImageTextSpace,
(Height - ImageHeight) / 2,
ImageWidth,
ImageHeight);
break;
}
if (PressOffset && ControlState == ControlState.Pressed && CurrentMousePosition == ButtonMousePosition.Button)
{
imageRect.X += 1;
imageRect.Y += 1;
textRect.X += 1;
textRect.Y += 1;
}
if (RightToLeft == RightToLeft.Yes)
{
imageRect.X = ButtonRect.Width - imageRect.Right;
textRect.X = ButtonRect.Width - textRect.Right;
}
}
///
///
///
///
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
base.OnPaintBackground(e);
Graphics g = e.Graphics;
//Rectangle imageRect;//图像区域
//Rectangle textRect;//文字区域
this.CalculateRect(out Rectangle imageRect, out Rectangle textRect, g);
g.SmoothingMode = SmoothingMode.AntiAlias;
Color baseColor;
Color borderColor;
Color innerBorderColor = this.BaseColor;//Color.FromArgb(200, 255, 255, 255); ;
if (Enabled)
{
switch (ControlState)
{
case ControlState.Hover:
baseColor = GetColor(BaseColor, 0, -35, -24, -30);
borderColor = BaseColor;
break;
case ControlState.Pressed:
baseColor = GetColor(BaseColor, 0, -35, -24, -9);
borderColor = BaseColor;
break;
default:
baseColor = BaseColor;
borderColor = BaseColor;
break;
}
}
else
{
baseColor = SystemColors.ControlDark;
borderColor = SystemColors.ControlDark;
}
this.RenderBackgroundInternal(
g,
ClientRectangle,
baseColor,
borderColor,
innerBorderColor,
RoundStyle,
Radius,
0.35f,
false,
true,
LinearGradientMode.Vertical);
if (Image != null)
{
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImage(Image, imageRect, 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel);
}
TextRenderer.DrawText(g, Text, Font, textRect, ForeColor, GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
}
private Color GetColor(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }
return Color.FromArgb(a, r, g, b);
}
internal void RenderBackgroundInternal(
Graphics g,
Rectangle rect,
Color baseColor,
Color borderColor,
Color innerBorderColor,
RoundStyle style,
int roundWidth,//圆角半径
float basePosition,
bool drawBorder,
bool drawGlass,
LinearGradientMode mode)
{
if (drawBorder)//是否画边框
{
rect.Width--;
rect.Height--;
}
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
{
Color[] colors = new Color[4];
if (ColorGradient)
{
colors[0] = GetColor(baseColor, 0, 35, 24, 9);
colors[1] = GetColor(baseColor, 0, 0, 0, 0);
colors[2] = baseColor;
colors[3] = GetColor(baseColor, 0, 0, 0, 0);
}
else
{
colors[0] = baseColor;
colors[1] = baseColor;
colors[2] = baseColor;
colors[3] = baseColor;
}
ColorBlend blend = new ColorBlend()
{
Positions = new float[] { 0.0f, basePosition, basePosition, 1.0f },
Colors = colors
};
brush.InterpolationColors = blend;
if (style != RoundStyle.None)
{
using (GraphicsPath path =
Drawing.CreatePath(rect, roundWidth, style, false))
{
g.FillPath(brush, path);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
// rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
// rectTop.Width = (int)(rect.Width * basePosition);
}
using (GraphicsPath pathTop = Drawing.CreatePath(
rectTop, roundWidth, style, false))
{
if (ColorGradient)
{
using (SolidBrush brushAlpha =
new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillPath(brushAlpha, pathTop);
}
}
}
}
}
}
}
internal static TextFormatFlags GetTextFormatFlags(
ContentAlignment alignment,
bool rightToleft)
{
TextFormatFlags flags = TextFormatFlags.WordBreak |
TextFormatFlags.SingleLine;
if (rightToleft)
{
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
}
switch (alignment)
{
case ContentAlignment.BottomCenter:
flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
break;
case ContentAlignment.BottomLeft:
flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
break;
case ContentAlignment.BottomRight:
flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
break;
case ContentAlignment.MiddleCenter:
flags |= TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter;
break;
case ContentAlignment.MiddleLeft:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
break;
case ContentAlignment.MiddleRight:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
break;
case ContentAlignment.TopCenter:
flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
break;
case ContentAlignment.TopLeft:
flags |= TextFormatFlags.Top | TextFormatFlags.Left;
break;
case ContentAlignment.TopRight:
flags |= TextFormatFlags.Top | TextFormatFlags.Right;
break;
}
return flags;
}
}
}