Rounded edges in button C# (WinForms)

后端 未结 6 460
时光说笑
时光说笑 2020-11-29 07:07

\"It's

Hello, through some research around here and other sites, I\'ve made a roun

相关标签:
6条回答
  • 2020-11-29 07:23

    This is a tweak on TaW's answer to more easily tweak the borderRadius and borderThickness. If you get random white space between the border and the button background color, m needs to be tweaked.

    public class RoundedButton : Button
    {
      GraphicsPath GetRoundPath(RectangleF Rect, int radius)
      {
        float m = 2.75F;
        float r2 = radius / 2f;
        GraphicsPath GraphPath = new GraphicsPath();
    
        GraphPath.AddArc(Rect.X + m, Rect.Y + m, radius, radius, 180, 90);
        GraphPath.AddLine(Rect.X + r2 + m, Rect.Y + m, Rect.Width - r2 - m, Rect.Y + m);
        GraphPath.AddArc(Rect.X + Rect.Width - radius - m, Rect.Y + m, radius, radius, 270, 90);
        GraphPath.AddLine(Rect.Width - m, Rect.Y + r2, Rect.Width - m, Rect.Height - r2 - m);
        GraphPath.AddArc(Rect.X + Rect.Width - radius - m,
                       Rect.Y + Rect.Height - radius - m, radius, radius, 0, 90);
        GraphPath.AddLine(Rect.Width - r2 - m, Rect.Height - m, Rect.X + r2 - m, Rect.Height - m);
        GraphPath.AddArc(Rect.X + m, Rect.Y + Rect.Height - radius - m, radius, radius, 90, 90);
        GraphPath.AddLine(Rect.X + m, Rect.Height - r2 - m, Rect.X + m, Rect.Y + r2 + m);
    
        GraphPath.CloseFigure();
        return GraphPath;
      }
    
      protected override void OnPaint(PaintEventArgs e)
      {
        int borderRadius = 50;
        float borderThickness = 1.75f;
        base.OnPaint(e);
        RectangleF Rect = new RectangleF(0, 0, this.Width, this.Height);
        GraphicsPath GraphPath = GetRoundPath(Rect, borderRadius);
    
        this.Region = new Region(GraphPath);
        using (Pen pen = new Pen(Color.Silver, borderThickness))
        {
          pen.Alignment = PenAlignment.Inset;
          e.Graphics.DrawPath(pen, GraphPath);
        }
      }
    }
    

    Cheers!

    0 讨论(0)
  • 2020-11-29 07:24

    Short of painting it yourself, I don't think there's anything you can do. The base button paint logic isn't written as "show a blue highlight around such-and-such portion of whatever the window region is". Instead, it's written with the type of region it expects -- a rectangular one. So the base paint is always going to paint a rectangular image into a cropped shape. You'll have an easier time of such things in WPF.

    0 讨论(0)
  • 2020-11-29 07:29
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Text;
    using System.Linq;
    using System.Reflection;
    using System.Windows.Forms;
    
    namespace ButtonRounded
    {
        public enum ButtonAction
        {
            Highlight,
            Click,
            Disabled,
            Normal,
        }
    public enum ShadowPosition
    {
        BottomRight,
        Bottom,
        BottomLeft,
        Left,
        TopLeft,
        Top,
        TopRight,
        Right,
    }
    
    public enum ShadowSize
    {
        Thin,
        Normal,
        Thick,
        None,
    }
    
    public static class ControlExtensions
    {
        public static T Clone<T>(this T controlToClone)
            where T : Control
        {
            PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    
            T instance = Activator.CreateInstance<T>();
    
            foreach (PropertyInfo propInfo in controlProperties)
            {
                if (propInfo.CanWrite && propInfo.Name != "WindowTarget")
                {
                    propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null);
                }
            }
    
            return instance;
        }
    
        public static void Copy<T>(this T controlToClone, ref T targetControl)
            where T : Control
        {
            foreach (PropertyInfo propInfo in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (propInfo.CanWrite && propInfo.Name != "WindowTarget")
                {
                    propInfo.SetValue(targetControl, propInfo.GetValue(controlToClone, null), null);
                }
            }
        }
    }
    
    public class RoundedButtons : IDisposable
    {
        public bool IsDisposed;
        private readonly Dictionary<Button, Button> _ButtonDataDictionary = new Dictionary<Button, Button>();
    
        public RoundedButtons()
        {
            MouseEventClick = (sender, e) => Button_MouseAction(sender, ButtonAction.Click);
            MouseEventHighlight = (sender, e) => Button_MouseAction(sender, ButtonAction.Highlight);
            EventHighlight = (sender, e) => Button_MouseAction(sender, ButtonAction.Highlight);
            EventNormal = (sender, e) => Button_MouseAction(sender, ButtonAction.Normal);
        }
    
        private event EventHandler EventHighlight;
    
        private event EventHandler EventNormal;
    
        private event MouseEventHandler MouseEventClick;
    
        private event MouseEventHandler MouseEventHighlight;
    
        public int Btn_CornerRadius { get; set; } = 8;
        public int Btn_LineWidth { get; set; } = 1;
        public ShadowPosition Btn_ShadowLocation { get; set; }
        public ShadowSize Btn_ShadowWidth { get; set; } = ShadowSize.Normal;
        public Padding Btn_TextPadding { get; set; } = new Padding(0);
    
        public Color ClickBGColor { get; set; } = Color.Empty;
        public Color ClickLineColor { get; set; } = Color.Black;
        public Color ClickShadowColor { get; set; } = Color.Black;
        public Color ClickTextColor { get; set; } = Color.GhostWhite;
        public Color DisabledBGColor { get; set; } = Color.Empty;
        public Color DisabledLineColor { get; set; } = Color.LightGray;
        public Color DisabledShadowColor { get; set; } = Color.DarkGray;
        public Color DisabledTextColor { get; set; } = Color.Gray;
        public Color HighlightBGColor { get; set; } = Color.Empty;
        public Color HighlightLineColor { get; set; } = Color.Blue;
        public Color HighlightShadowColor { get; set; } = Color.Black;
        public Color HighlightTextColor { get; set; } = Color.Empty;
        public Color MainBGColor { get; set; } = Color.Empty;
        public Color MainLineColor { get; set; } = Color.Black;
        public Color MainShadowColor { get; set; } = Color.DarkGray;
        public Color MainTextColor { get; set; } = Color.Empty;
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        public string GetButtonText(Button button)
        {
            string text = "";
            _ButtonDataDictionary.TryGetValue(button, out Button copy);
            if (copy != null)
            {
                text = copy.Text;
            }
    
            return text;
        }
    
        public void PaintButton(object sender)
        {
            if (sender is Button b)
            {
                _ButtonDataDictionary.Add(b, b.Clone());
                b.TabStop = false;
                b.FlatStyle = FlatStyle.Flat;
                b.FlatAppearance.BorderSize = 0;
                b.FlatAppearance.MouseDownBackColor = Color.FromArgb(0, 255, 255, 255);
                b.FlatAppearance.MouseOverBackColor = Color.FromArgb(0, 255, 255, 255);
                b.FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);
                b.BackColor = Color.FromArgb(0, 255, 255, 255);
    
                //Clear text field to prevent double drawn text with Transparency.
                b.Text = "";
    
                b.Paint += B_Paint;
                b.EnabledChanged += EventNormal;
                b.MouseEnter += EventHighlight;
                b.MouseLeave += EventNormal;
                b.MouseDown += MouseEventClick;
                b.MouseUp += MouseEventHighlight;
                b.TextChanged += B_TextChanged;
    
                b.Refresh();
            }
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (!IsDisposed && disposing)
            {
                Button[] keys = _ButtonDataDictionary.Keys.ToArray();
                for (int i = 0; i < keys.Length; i++)
                {
                    Button b = _ButtonDataDictionary.ElementAt(i).Key;
                    Button copy = _ButtonDataDictionary.ElementAt(i).Value;
    
                    b.Paint -= B_Paint;
                    b.EnabledChanged -= EventNormal;
                    b.MouseEnter -= EventHighlight;
                    b.MouseLeave -= EventNormal;
                    b.MouseDown -= MouseEventClick;
                    b.MouseUp -= MouseEventHighlight;
                    b.TextChanged -= B_TextChanged;
                    copy?.Copy(ref b);
                    copy?.Dispose();
                    b?.Refresh();
                }
    
                _ButtonDataDictionary.Clear();
                IsDisposed = true;
            }
        }
    
        private void B_Paint(object sender, PaintEventArgs e)
        {
            RoundedButton_Paint(sender, e, ButtonAction.Normal);
        }
    
        private void B_Paint_Click(object sender, PaintEventArgs e)
        {
            RoundedButton_Paint(sender, e, ButtonAction.Click);
        }
    
        private void B_Paint_Disable(object sender, PaintEventArgs e)
        {
            RoundedButton_Paint(sender, e, ButtonAction.Disabled);
        }
    
        private void B_Paint_Hightlight(object sender, PaintEventArgs e)
        {
            RoundedButton_Paint(sender, e, ButtonAction.Highlight);
        }
    
        private void B_TextChanged(object sender, EventArgs e)
        {
            if (sender is Button b)
            {
                _ButtonDataDictionary.TryGetValue(b, out Button copy);
                copy.Text = b.Text;
                b.TextChanged -= B_TextChanged;
                b.Text = "";
                b.TextChanged += B_TextChanged;
            }
        }
    
        private void Button_MouseAction(object sender, ButtonAction action)
        {
            if (sender is Button b)
            {
                b.Paint -= B_Paint_Disable;
                b.Paint -= B_Paint_Click;
                b.Paint -= B_Paint_Hightlight;
                b.Paint -= B_Paint;
    
                b.Paint += action switch
                {
                    ButtonAction.Click => B_Paint_Click,
                    ButtonAction.Disabled => B_Paint_Disable,
                    ButtonAction.Highlight => B_Paint_Hightlight,
                    _ => B_Paint
                };
    
                b.Refresh();
            }
        }
    
        private Rectangle[] CalculateRects(Button b, int shadowWidth)
        {
            int width = b.Size.Width - 1;
            int height = b.Size.Height - 1;
            if (Btn_ShadowLocation.ToString().Contains("Bottom") || Btn_ShadowLocation.ToString().Contains("Top"))
            {
                height -= Btn_LineWidth * 2; height -= shadowWidth;
            }
    
            if (Btn_ShadowLocation.ToString().Contains("Right") || Btn_ShadowLocation.ToString().Contains("Left"))
            {
                width -= Btn_LineWidth * 2; width -= shadowWidth;
            }
    
            Size size = new Size(width, height);
            Rectangle shadow = new Rectangle(new Point(0, 0), size);
            Rectangle button = new Rectangle(new Point(0, 0), size);
    
            if (Btn_ShadowLocation.ToString().Contains("Right"))
            {
                shadow.X = shadowWidth;
                button.X = 0;
            }
    
            if (Btn_ShadowLocation.ToString().Contains("Bottom"))
            {
                shadow.Y = shadowWidth;
                button.Y = 0;
            }
    
            if (Btn_ShadowLocation.ToString().Contains("Left"))
            {
                shadow.X = 0;
                button.X = shadowWidth;
            }
    
            if (Btn_ShadowLocation.ToString().Contains("Top"))
            {
                shadow.Y = 0;
                button.Y = shadowWidth;
            }
    
            return new Rectangle[] { shadow, button };
        }
    
        private void RoundedButton_Paint(object sender, PaintEventArgs e, ButtonAction action = ButtonAction.Normal)
        {
            if (sender is Button b)
            {
                if (!b.Enabled)
                {
                    action = ButtonAction.Disabled;
                }
    
                //================Setup================
                e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
                e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
                e.Graphics.CompositingQuality = CompositingQuality.HighSpeed;
                e.Graphics.TextRenderingHint = TextRenderingHint.SystemDefault; //Causes issues with application text.
    
                StringFormat stringFormat = new StringFormat
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                };
    
                int shadowWidth = (Btn_ShadowWidth == ShadowSize.Thin) ? 1 : (Btn_ShadowWidth == ShadowSize.Normal) ? 2 : (Btn_ShadowWidth == ShadowSize.Thick) ? 3 : 0;
                Rectangle[] rect = CalculateRects(b, shadowWidth);
                _ButtonDataDictionary.TryGetValue(b, out Button copy);
    
                //=====================================
                //===============Colors================
                Color shadowColor = action switch
                {
                    ButtonAction.Click => ClickShadowColor,
                    ButtonAction.Disabled => DisabledShadowColor,
                    ButtonAction.Highlight => HighlightShadowColor,
                    ButtonAction.Normal => MainShadowColor,
                    _ => MainShadowColor
                };
                shadowColor = shadowColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : shadowColor;
    
                Color bgColor = action switch
                {
                    ButtonAction.Click => ClickBGColor,
                    ButtonAction.Disabled => DisabledBGColor,
                    ButtonAction.Highlight => HighlightBGColor,
                    ButtonAction.Normal => MainBGColor,
                    _ => MainBGColor
                };
                bgColor = bgColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : bgColor;
                bgColor = bgColor.IsEmpty ? copy.BackColor : bgColor;
    
                Color lineColor = action switch
                {
                    ButtonAction.Click => ClickLineColor,
                    ButtonAction.Disabled => DisabledLineColor,
                    ButtonAction.Highlight => HighlightLineColor,
                    ButtonAction.Normal => MainLineColor,
                    _ => MainLineColor
                };
                lineColor = lineColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : lineColor;
    
                Color textColor = action switch
                {
                    ButtonAction.Click => ClickTextColor,
                    ButtonAction.Disabled => DisabledTextColor,
                    ButtonAction.Highlight => HighlightTextColor,
                    ButtonAction.Normal => MainTextColor,
                    _ => MainTextColor
                };
                textColor = textColor == Color.Transparent ? Color.FromArgb(0, 255, 255, 255) : textColor;
                if (shadowWidth > 0)
                {
                    //Draw shadow in the back
                    using Brush shadowBrush = new SolidBrush(shadowColor);
                    using Pen shadowPen = new Pen(shadowBrush, shadowWidth * 2);
                    if (b.Parent is PictureBox || copy.BackColor == Color.FromArgb(0, 255, 255, 255))
                    {
                        e.Graphics.DrawRoundedRectanglePart(shadowPen, rect[0], Btn_CornerRadius, Btn_ShadowLocation);
                    }
                    else
                    {
                        e.Graphics.DrawRoundedRectangle(shadowPen, rect[0], Btn_CornerRadius);
                    }
                }
    
                //Draw over any existing button graphics
                using Brush clearBrush = new SolidBrush((b.Parent is PictureBox) ? Color.FromArgb(0, 255, 255, 255) : ExtensionMethods.GetParentBackColor(b));
                e.Graphics.FillRoundedRectangle(clearBrush, rect[1], Btn_CornerRadius);
    
                //Draw background color of the button
                using Brush backBrush = new SolidBrush(bgColor);
                e.Graphics.FillRoundedRectangle(backBrush, rect[1], Btn_CornerRadius);
    
                //Draw outline of the button
                using Brush buttonBrush = new SolidBrush(lineColor);
                using Pen buttonPen = new Pen(buttonBrush, Btn_LineWidth);
                e.Graphics.DrawRoundedRectangle(buttonPen, rect[1], Btn_CornerRadius);
    
                //Draw text of the button
                //Button text is set to "" so that transparency will not show the original text.
                //I use a copy of the button to pull the text to draw.
                using Brush textBrush = new SolidBrush(textColor.IsEmpty ? b.ForeColor : textColor);
                Rectangle rectangleText = new Rectangle(
                    rect[1].X + Btn_TextPadding.Left,
                    rect[1].Y + Btn_TextPadding.Top,
                    rect[1].Width - Btn_TextPadding.Right,
                    rect[1].Height - Btn_TextPadding.Bottom
                    );
                e.Graphics.DrawString(copy.Text, b.Font, textBrush, rectangleText, stringFormat);
    
            }
        }
    }
    
    internal static class ExtensionMethods
    {
        public static void DrawRoundedRectangle(this Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius)
        {
            using GraphicsPath path = RoundedRect(bounds, cornerRadius);
            graphics.DrawPath(pen, path);
        }
    
        public static void DrawRoundedRectanglePart(this Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius, ShadowPosition position)
        {
            using GraphicsPath path = RoundedRectPart(bounds, cornerRadius, position);
            path.Flatten(new Matrix(), 0.12f);
    
            PointF prevP = new PointF();
            int total = path.PathPoints.Length;
            int count = 1;
            float penSize;
    
            int trim;
            if (position == ShadowPosition.Bottom || position == ShadowPosition.Top || position == ShadowPosition.Left || position == ShadowPosition.Right)
            {
                trim = 1;
            }
            else
            {
                trim = 2;
            }
    
            foreach (PointF p in path.PathPoints)
            {
                if (prevP.IsEmpty || count <= trim || count >= total - trim)
                {
                    prevP = p; count++; continue;
                }
    
                if (count <= 3 || count >= total - 3)
                {
                    penSize = 1;
                }
                else if (count <= 5 || count >= total - 5)
    
                {
                    penSize = 2;
                }
                else if (count <= 8 || count >= total - 8)
                {
                    penSize = 3;
                }
                else
                {
                    penSize = pen.Width;
                }
    
                if (penSize > pen.Width)
                {
                    penSize = pen.Width;
                }
    
                graphics.DrawLine(new Pen(pen.Color, penSize), prevP, p);
                prevP = p;
                count++;
            }
        }
    
        public static void FillRoundedRectangle(this Graphics graphics, Brush brush, Rectangle bounds, int cornerRadius)
        {
            using GraphicsPath path = RoundedRect(bounds, cornerRadius);
            graphics.FillPath(brush, path);
        }
    
        internal static Color GetParentBackColor(object sender)
        {
            Color c;
            try
            {
                if ((sender as dynamic)?.Parent != null)
                {
                    c = (sender as dynamic)?.Parent.BackColor;
                }
                else
                {
                    c = Color.White;
                }
            }
            catch
            {
                c = Color.White;
            }
    
            if (c == Color.Transparent)
            {
                try
                {
                    if ((sender as dynamic)?.Parent != null)
                    {
                        c = GetParentBackColor((sender as dynamic)?.Parent);
                    }
                    else
                    {
                        c = Color.White;
                    }
                }
                catch
                {
                    c = Color.White;
                }
            }
    
            return c;
        }
    
        internal static GraphicsPath RoundedRect(Rectangle bounds, int radius)
        {
            int diameter = radius * 2;
            Size size = new Size(diameter, diameter);
            Rectangle arc = new Rectangle(bounds.Location, size);
            GraphicsPath path = new GraphicsPath { FillMode = FillMode.Alternate };
    
            if (radius == 0)
            {
                path.AddRectangle(bounds);
                return path;
            }
    
            path.AddArc(arc, 180, 90);
    
            arc.X = bounds.Right - diameter;
            path.AddArc(arc, 270, 90);
    
            arc.Y = bounds.Bottom - diameter;
            path.AddArc(arc, 0, 90);
    
            arc.X = bounds.Left;
            path.AddArc(arc, 90, 90);
    
            path.CloseFigure();
            return path;
        }
    
        internal static GraphicsPath RoundedRectPart(Rectangle bounds, int radius, ShadowPosition position)
        {
            int diameter = radius * 2;
            Size size = new Size(diameter, diameter);
            Rectangle arc = new Rectangle(bounds.Location, size);
            GraphicsPath path = new GraphicsPath { FillMode = FillMode.Alternate, };
    
            if (radius == 0)
            {
                path.AddRectangle(bounds);
                return path;
            }
    
            if (position == ShadowPosition.Right)
            {
                arc.X = bounds.Right - diameter;
                path.AddArc(arc, 270, 90);
                arc.Y = bounds.Bottom - diameter;
                path.AddArc(arc, 0, 90);
            }
            else if (position == ShadowPosition.BottomRight)
            {
                arc.X = bounds.Right - diameter;
                path.AddArc(arc, 270, 90);
                arc.Y = bounds.Bottom - diameter;
                path.AddArc(arc, 0, 90);
                arc.X = bounds.Left;
                path.AddArc(arc, 90, 90);
            }
            else if (position == ShadowPosition.Bottom)
            {
                arc.X = bounds.Right - diameter;
                arc.Y = bounds.Bottom - diameter;
                path.AddArc(arc, 0, 90);
                arc.X = bounds.Left;
                path.AddArc(arc, 90, 90);
            }
            else if (position == ShadowPosition.BottomLeft)
            {
                arc.X = bounds.Right - diameter;
                arc.Y = bounds.Bottom - diameter;
                path.AddArc(arc, 0, 90);
                arc.X = bounds.Left;
                path.AddArc(arc, 90, 90);
                arc.Y = bounds.Top;
                path.AddArc(arc, 180, 90);
            }
            else if (position == ShadowPosition.Left)
            {
                arc.Y = bounds.Bottom - diameter;
                arc.X = bounds.Left;
                path.AddArc(arc, 90, 90);
                arc.Y = bounds.Top;
                path.AddArc(arc, 180, 90);
            }
            else if (position == ShadowPosition.TopLeft)
            {
                arc.Y = bounds.Bottom - diameter;
                arc.X = bounds.Left;
                path.AddArc(arc, 90, 90);
                arc.Y = bounds.Top;
                path.AddArc(arc, 180, 90);
                arc.X = bounds.Right - diameter;
                path.AddArc(arc, 270, 90);
            }
            else if (position == ShadowPosition.Top)
            {
                path.AddArc(arc, 180, 90);
                arc.X = bounds.Right - diameter;
                path.AddArc(arc, 270, 90);
            }
            else if (position == ShadowPosition.TopRight)
            {
                path.AddArc(arc, 180, 90);
                arc.X = bounds.Right - diameter;
                path.AddArc(arc, 270, 90);
                arc.Y = bounds.Bottom - diameter;
                path.AddArc(arc, 0, 90);
            }
    
            return path;
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-29 07:31

    You can use a WebBrowser, make a button with HTML and CSS, then use webbrowser.DocumentText = "your html";

    0 讨论(0)
  • 2020-11-29 07:35
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.ComponentModel;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    
    namespace button2
    {
        public partial class Form1 : Form
        {
            private Button button1;
            private GroupBox box;
            public Form1()
            {
                InitializeComponent();
                show();
            }
            private void show()
            {
                box = new GroupBox();
                button1 = new Button();
                button1.Location = new Point(50, 50);
                ElipseControl nn = new ElipseControl();            
                nn.TargetControl = button1;            
                button1.Text = "First Name";
                button1.BackColor = Color.Cyan;
                button1.FlatStyle = FlatStyle.Flat;
                button1.FlatAppearance.BorderSize = 0;
                button1.FlatAppearance.BorderColor = Color.White;
                nn.CornerRadius = 10;
    
                button1.ForeColor = Color.Blue;
                button1.Font = new Font("Arial", 9, FontStyle.Bold);
                box.Controls.Add(button1);
                box.AutoSize = true;
    
    
                this.Controls.Add(box);
    
            }
        }
        class ElipseControl : Component
        {
            [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
            public static extern IntPtr CreateRoundRectRgn
                (
                   int nLeftRect,
                   int nTopRect,
                   int nRightRect,
                   int nBottomRect,
                   int nWidthEllipse,
                   int nHeightEllipse
                );
            private Control _cntrl;
            private int _CornerRadius = 30;
    
            public Control TargetControl
            {
                get { return _cntrl; }
                set
                {
                    _cntrl = value;
                    _cntrl.SizeChanged += (sender, eventArgs) => _cntrl.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, _cntrl.Width, _cntrl.Height, _CornerRadius, _CornerRadius));
                }
            }
    
            public int CornerRadius
            {
                get { return _CornerRadius; }
                set
                {
                    _CornerRadius = value;
                    if (_cntrl != null)
                        _cntrl.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, _cntrl.Width, _cntrl.Height, _CornerRadius, _CornerRadius));
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 07:38

    This is a quick one, you may want to fine tune things and optimize quite a few details..

    class RoundedButton : Button
    {
       GraphicsPath GetRoundPath(RectangleF Rect, int radius)
       {
          float r2 = radius / 2f;
          GraphicsPath GraphPath = new GraphicsPath();
          GraphPath.AddArc(Rect.X, Rect.Y, radius, radius, 180, 90);
          GraphPath.AddLine(Rect.X + r2, Rect.Y, Rect.Width - r2, Rect.Y);
          GraphPath.AddArc(Rect.X + Rect.Width - radius, Rect.Y, radius, radius, 270, 90);
          GraphPath.AddLine(Rect.Width, Rect.Y + r2, Rect.Width, Rect.Height - r2);
          GraphPath.AddArc(Rect.X + Rect.Width - radius, 
                           Rect.Y + Rect.Height - radius, radius, radius, 0, 90);
          GraphPath.AddLine(Rect.Width - r2, Rect.Height, Rect.X + r2, Rect.Height);
          GraphPath.AddArc(Rect.X, Rect.Y + Rect.Height - radius, radius, radius, 90, 90);
          GraphPath.AddLine(Rect.X, Rect.Height - r2, Rect.X, Rect.Y + r2);
          GraphPath.CloseFigure();
          return GraphPath;
       }
    
       protected override void OnPaint(PaintEventArgs e)
       {
          base.OnPaint(e);
          RectangleF Rect = new RectangleF(0, 0, this.Width, this.Height);
          using (GraphicsPath GraphPath = GetRoundPath(Rect, 50))
          {
            this.Region = new Region(GraphPath);
            using (Pen pen = new Pen(Color.CadetBlue, 1.75f))
            {
                pen.Alignment = PenAlignment.Inset;
                e.Graphics.DrawPath(pen, GraphPath);
            }
          }
       }
    }
    

    Obviously, since we have a class we can cache the GraphicsPath in a class variable. And of course you pick the color..

    enter image description here

    0 讨论(0)
提交回复
热议问题