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; } } }