【问题标题】:Rounded edges in button C# (WinForms)按钮 C# (WinForms) 中的圆角边缘
【发布时间】:2015-04-13 17:21:05
【问题描述】:

您好,通过对这里和其他网站的一些研究,我制作了一个圆形边缘按钮。

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    Rectangle Rect = new Rectangle(0, 0, this.Width, this.Height);
    GraphicsPath GraphPath = new GraphicsPath();
    GraphPath.AddArc(Rect.X, Rect.Y, 50, 50, 180, 90);
    GraphPath.AddArc(Rect.X + Rect.Width - 50, Rect.Y, 50, 50, 270, 90);
    GraphPath.AddArc(Rect.X + Rect.Width - 50, Rect.Y + Rect.Height - 50, 50, 50, 0, 90);
    GraphPath.AddArc(Rect.X, Rect.Y + Rect.Height - 50, 50, 50, 90, 90);
    this.Region = new Region(GraphPath);
}

我面临的问题是按钮的“蓝色突出显示”:它显示在大部分按钮上,但不显示在圆边上,因此我的按钮部分突出显示,部分未突出显示(在边缘)。我能做些什么来解决这个问题?谢谢。

PS:我不能使用 WPF。该应用程序适用于一台非常旧的计算机;所以,请不要建议它。此外,客户没有钱购买更新的计算机。

【问题讨论】:

  • 旁注:您应该只设置一次区域,而不是每次绘制。
  • 查看我的更新答案!

标签: c# winforms button graphics rounded-corners


【解决方案1】:

这是一个快速的,你可能想要微调一些东西并优化很多细节..

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

显然,由于我们有一个类,我们可以将GraphicsPath 缓存在一个类变量中。当然,你选择颜色..

【讨论】:

  • 老电脑做应用太麻烦了……谢谢分享这段代码!
  • 这是一个很好的解决方案。但边界线仍然不是很令人印象深刻。实在是太蹩脚了,让我没用这个。
  • 好吧,你可以试试 Graphics.SmoothingMode 但你是对的:Winforms 不擅长浮华……
  • @TaW,非常感谢您提供的精确代码,但是GetRoundPath函数的第二个参数名称,不应该是diameter而不是radius吗? (这就是我个人对 AddArc 函数的理解)那么,float r2 变量可以简单地称为radius...
【解决方案2】:

这是对 TaW 答案的调整,可以更轻松地调整边界半径和边界厚度。如果边框和按钮背景颜色之间出现随机空白,则需要调整 m。

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

干杯!

【讨论】:

    【解决方案3】:
    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));
                }
            }
        }
    }
    

    【讨论】:

    • 能否请您写一点评论,描述您的代码的作用以及为什么它可能会有所帮助?
    【解决方案4】:
    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;
        }
    }
    

    }

    【讨论】:

      【解决方案5】:

      您可以使用网络浏览器,使用 HTML 和 CSS 制作按钮,然后使用 webbrowser.DocumentText = "your html";

      【讨论】:

      • 你真的可以在 WinForms 上使用 WebBrowser 吗?
      • @Soulblazer 为什么不呢?
      • 只是想知道。直到现在我才听说这是可能的。我以为你误读了这个问题之类的。很抱歉,谢谢。
      【解决方案6】:

      你自己画,我不认为有什么可以做的。基本按钮绘制逻辑没有写为“在窗口区域的某某部分周围显示蓝色突出显示”。相反,它是用它所期望的区域类型编写的——一个矩形区域。所以基础颜料总是将矩形图像绘制成裁剪后的形状。您将在 WPF 中更轻松地处理此类事情。

      【讨论】:

      • 尝试告诉那些希望应用程序美观但又不想购买更新、图形功能更强大的计算机的客户。我不知道怎么给他一些理智。仅仅因为计算机就是计算机,并不意味着它对所有事物都有用。
      • 另外,我注意到您(如 msdn.microsoft.com/en-us/library/… 上的文档)正在您的 Paint 事件处理程序中设置 Region 属性。您可能只想在 Layout 事件的处理程序中执行此操作。该文档有一个糟糕的示例,我将在那里发表评论以说明这一点。 :)
      • @Michael 很好,这是来自文档的一些糟糕的建议... :-\
      猜你喜欢
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2020-12-02
      相关资源
      最近更新 更多