因為原生的按鈕功能 無法做到像圓角這樣的按鈕功能
因此需要擴充複寫原本的來做到這種需求
來源:http://bbs.csdn.net/topics/300051450
二話不多說
private void roundButton_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
System.Drawing.Drawing2D.GraphicsPath buttonPath =
new System.Drawing.Drawing2D.GraphicsPath();
// Set a new rectangle to the same size as the button's
// ClientRectangle property.
System.Drawing.Rectangle newRectangle = roundButton.ClientRectangle;
// Decrease the size of the rectangle.
newRectangle.Inflate(-10, -10);
// Draw the button's border.
e.Graphics.DrawEllipse(System.Drawing.Pens.Black, newRectangle);
// Increase the size of the rectangle to include the border.
newRectangle.Inflate( 1, 1);
// Create a circle within the new rectangle.
buttonPath.AddEllipse(newRectangle);
//設置按钮的Region.
roundButton.Region = new System.Drawing.Region(buttonPath);
}
或是寫一個類別 去繼承並寫修改覆蓋
public class ButtonEx : Button { private Color _baseColor = Color.FromArgb(51, 161, 224); private ControlState _controlState; private int _imageWidth = 18; private RoundStyle _roundStyle = RoundStyle.All; private int _radius = 8; public ButtonEx() : base() { SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); } [DefaultValue(typeof(Color), "51, 161, 224")] public Color BaseColor { get { return _baseColor; } set { _baseColor = value; base.Invalidate(); } } [DefaultValue(18)] public int ImageWidth { get { return _imageWidth; } set { if (value != _imageWidth) { _imageWidth = value < 12 ? 12 : value; base.Invalidate(); } } } [DefaultValue(typeof(RoundStyle), "1")] public RoundStyle RoundStyle { get { return _roundStyle; } set { if (_roundStyle != value) { _roundStyle = value; base.Invalidate(); } } } [DefaultValue(8)] public int Radius { get { return _radius; } set { if (_radius != value) { _radius = value < 4 ? 4 : value; base.Invalidate(); } } } 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) { 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; } } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); base.OnPaintBackground(e); Graphics g = e.Graphics; Rectangle imageRect; Rectangle textRect; CalculateRect(out imageRect, out textRect); g.SmoothingMode = SmoothingMode.AntiAlias; Color baseColor; Color borderColor; Color innerBorderColor = Color.FromArgb(200, 255, 255, 255); ; if (Enabled) { switch (ControlState) { case ControlState.Hover: baseColor = GetColor(_baseColor, 0, -13, -8, -3); 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; } RenderBackgroundInternal( g, ClientRectangle, baseColor, borderColor, innerBorderColor, RoundStyle, Radius, 0.35f, true, 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 void CalculateRect( out Rectangle imageRect, out Rectangle textRect) { imageRect = Rectangle.Empty; textRect = Rectangle.Empty; if (Image == null) { textRect = new Rectangle( 2, 0, Width - 4, Height); return; } switch (TextImageRelation) { case TextImageRelation.Overlay: imageRect = new Rectangle( 2, (Height - ImageWidth) / 2, ImageWidth, ImageWidth); textRect = new Rectangle( 2, 0, Width - 4, Height); break; case TextImageRelation.ImageAboveText: imageRect = new Rectangle( (Width - ImageWidth) / 2, 2, ImageWidth, ImageWidth); textRect = new Rectangle( 2, imageRect.Bottom, Width, Height - imageRect.Bottom - 2); break; case TextImageRelation.ImageBeforeText: imageRect = new Rectangle( 2, (Height - ImageWidth) / 2, ImageWidth, ImageWidth); textRect = new Rectangle( imageRect.Right + 2, 0, Width - imageRect.Right - 4, Height); break; case TextImageRelation.TextAboveImage: imageRect = new Rectangle( (Width - ImageWidth) / 2, Height - ImageWidth - 2, ImageWidth, ImageWidth); textRect = new Rectangle( 0, 2, Width, Height - imageRect.Y - 2); break; case TextImageRelation.TextBeforeImage: imageRect = new Rectangle( Width - ImageWidth - 2, (Height - ImageWidth) / 2, ImageWidth, ImageWidth); textRect = new Rectangle( 2, 0, imageRect.X - 2, Height); break; } if (RightToLeft == RightToLeft.Yes) { imageRect.X = Width - imageRect.Right; textRect.X = Width - textRect.Right; } } 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]; colors[0] = GetColor(baseColor, 0, 35, 24, 9); colors[1] = GetColor(baseColor, 0, 13, 8, 3); colors[2] = baseColor; colors[3] = GetColor(baseColor, 0, 68, 69, 54); ColorBlend blend = new ColorBlend(); blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f }; blend.Colors = colors; brush.InterpolationColors = blend; if (style != RoundStyle.None) { using (GraphicsPath path = GraphicsPathHelper.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 = GraphicsPathHelper.CreatePath( rectTop, roundWidth, RoundStyle.Top, false)) { using (SolidBrush brushAlpha = new SolidBrush(Color.FromArgb(80, 255, 255, 255))) { g.FillPath(brushAlpha, pathTop); } } } if (drawGlass) { RectangleF glassRect = rect; if (mode == LinearGradientMode.Vertical) { glassRect.Y = rect.Y + rect.Height * basePosition; glassRect.Height = (rect.Height - rect.Height * basePosition) * 2; } else { glassRect.X = rect.X + rect.Width * basePosition; glassRect.Width = (rect.Width - rect.Width * basePosition) * 2; } DrawGlass(g, glassRect, 170, 0); } if (drawBorder) { using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false)) { using (Pen pen = new Pen(borderColor)) { g.DrawPath(pen, path); } } rect.Inflate(-1, -1); using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false)) { using (Pen pen = new Pen(innerBorderColor)) { g.DrawPath(pen, path); } } } } else { g.FillRectangle(brush, rect); 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 (SolidBrush brushAlpha = new SolidBrush(Color.FromArgb(80, 255, 255, 255))) { g.FillRectangle(brushAlpha, rectTop); } } if (drawGlass) { RectangleF glassRect = rect; if (mode == LinearGradientMode.Vertical) { glassRect.Y = rect.Y + rect.Height * basePosition; glassRect.Height = (rect.Height - rect.Height * basePosition) * 2; } else { glassRect.X = rect.X + rect.Width * basePosition; glassRect.Width = (rect.Width - rect.Width * basePosition) * 2; } DrawGlass(g, glassRect, 200, 0); } if (drawBorder) { using (Pen pen = new Pen(borderColor)) { g.DrawRectangle(pen, rect); } rect.Inflate(-1, -1); using (Pen pen = new Pen(innerBorderColor)) { g.DrawRectangle(pen, rect); } } } } } private void DrawGlass( Graphics g, RectangleF glassRect, int alphaCenter, int alphaSurround) { DrawGlass(g, glassRect, Color.White, alphaCenter, alphaSurround); } private void DrawGlass( Graphics g, RectangleF glassRect, Color glassColor, int alphaCenter, int alphaSurround) { using (GraphicsPath path = new GraphicsPath()) { path.AddEllipse(glassRect); using (PathGradientBrush brush = new PathGradientBrush(path)) { brush.CenterColor = Color.FromArgb(alphaCenter, glassColor); brush.SurroundColors = new Color[] { Color.FromArgb(alphaSurround, glassColor) }; brush.CenterPoint = new PointF( glassRect.X + glassRect.Width / 2, glassRect.Y + glassRect.Height / 2); g.FillPath(brush, path); } } } 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 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; } }
下面這個效果比較漂亮 也比較多 還可以同理的擴充TextBox功能