如何使用WinForms(.NET)绘制圆角矩形?

使用C#绘制矩形,我需要在每个边缘绘制弧线,首先绘制矩形,然后我需要单击按钮它将在边缘绘制弧线,我该怎么办?

C#中的图形类没有内置方法来绘制圆角矩形,但是有几种方法可以实现这种效果。 Jay Riggs答案中的链接提供了从哪里开始的好建议,另外我建议您查看这篇文章:

C# – 使用图形路径创建圆角矩形

首先,我们创建一个GraphicsPath,然后调用StartFigure,以便我们可以开始向路径添加边。 此代码的其余部分用于左上角和圆角矩形的顶行。 如果我们应该使这个角落圆角,我们添加一个弧 – 否则……

画一个圆角的矩形?

尝试:

扩展图形 – C#3.0的圆角矩形,字体度量和更多
扩展图形 – C#中的圆角矩形的实现

我知道这篇文章很老,但是在搜索C#中如何做圆角矩形时它是最受欢迎的,我遇到了一些问题。 AddArc方法是不准确的,因此如果您使用接受答案中的代码,您将获得一个时髦的圆角矩形。 左上角是正确的,右上角和左下角是畸形的,右下角太小。 我已经调整了代码中的一些内容以补偿AddArc的不准确性,我相信我有一个工作解决方案来创建一个合适的圆角矩形。 此版本还可以将矩形分为左上半部分和右下半部分,这对于进行3D效果的浅色/深色阴影非常方便。

设置窗口区域以及创建topleft / bottomright路径以使用浅色和黑色笔进行着色以进行着色的示例用法:

Region = new Region(RoundedRectangles.RoundedRectangle.Create(new Rectangle(0, 0, Size.Width, Size.Height), 8, RoundedRectangles.RoundedRectangle.RectangleCorners.TopRight | RoundedRectangles.RoundedRectangle.RectangleCorners.TopLeft)); TopLeftPath = RoundedRectangles.RoundedRectangle.Create(new Rectangle(0, 0, Size.Width, Size.Height), 8, RoundedRectangles.RoundedRectangle.RectangleCorners.TopRight | RoundedRectangles.RoundedRectangle.RectangleCorners.TopLeft, RoundedRectangles.RoundedRectangle.WhichHalf.TopLeft); BottomRightPath = RoundedRectangles.RoundedRectangle.Create(new Rectangle(0, 0, Size.Width-1, Size.Height-1), 8, RoundedRectangles.RoundedRectangle.RectangleCorners.TopRight | RoundedRectangles.RoundedRectangle.RectangleCorners.TopLeft, RoundedRectangles.RoundedRectangle.WhichHalf.BottomRight); 

最后是代码:

 using System; using System.Drawing; using System.Drawing.Drawing2D; namespace RoundedRectangles { public abstract class RoundedRectangle { [Flags] public enum RectangleCorners { None = 0, TopLeft = 1, TopRight = 2, BottomLeft = 4, BottomRight = 8, All = TopLeft | TopRight | BottomLeft | BottomRight } public enum WhichHalf { TopLeft, BottomRight, Both } static void Corner(GraphicsPath path, int x1, int y1, int x2, int y2, int x3, int y3) { path.AddLine(x1, y1, x2, y2); path.AddLine(x2, y2, x3, y3); } public static GraphicsPath Create(int x, int y, int width, int height, int radius, RectangleCorners corners, WhichHalf half) { if (radius <= 0) { GraphicsPath rectp = new GraphicsPath(); rectp.AddRectangle(new Rectangle(x, y, width, height)); return rectp; } int dia = radius * 2; Rectangle TLarc = new Rectangle(x, y, dia, dia); Rectangle TRarc = new Rectangle(x + width - dia - 1, y, dia, dia); Rectangle BRarc = new Rectangle(x + width - dia - 1, y + height - dia - 1, dia, dia); Rectangle BLarc = new Rectangle(x, y + height - dia - 1, dia, dia); Rectangle TLsquare = new Rectangle(x, y, radius, radius); Rectangle TRsquare = new Rectangle(x + width - radius, y, radius, radius); Rectangle BRsquare = new Rectangle(x + width - radius, y + height - radius, radius, radius); Rectangle BLsquare = new Rectangle(x, y + height - radius, radius, radius); GraphicsPath p = new GraphicsPath(); p.StartFigure(); if (half == WhichHalf.Both || half == WhichHalf.TopLeft) { if (corners.HasFlag(RectangleCorners.BottomLeft)) p.AddArc(BLarc, 135, 45); else p.AddLine(BLsquare.Left, BLsquare.Bottom, BLsquare.Left, BLsquare.Top); p.AddLine(BLsquare.Left, BLsquare.Top - 1, TLsquare.Left, TLsquare.Bottom + 1); if (corners.HasFlag(RectangleCorners.TopLeft)) p.AddArc(TLarc, 180, 90); else Corner(p, TLsquare.Left, TLsquare.Bottom, TLsquare.Left, TLsquare.Top, TLsquare.Right, TLsquare.Top); p.AddLine(TLsquare.Right + 1, TLsquare.Top, TRsquare.Left - 1, TRsquare.Top); if (corners.HasFlag(RectangleCorners.TopRight)) p.AddArc(TRarc, -90, 45); } if (half == WhichHalf.Both || half == WhichHalf.BottomRight) { if (corners.HasFlag(RectangleCorners.TopRight)) p.AddArc(TRarc, -45, 45); else p.AddLine(TRsquare.Right, TRsquare.Top, TRsquare.Right, TRsquare.Bottom); p.AddLine(TRsquare.Right, TRsquare.Bottom + 1, BRsquare.Right, BRsquare.Top - 1); if (corners.HasFlag(RectangleCorners.BottomRight)) p.AddArc(BRarc, 0, 90); else Corner(p, BRsquare.Right, BRsquare.Top, BRsquare.Right, BRsquare.Bottom, BRsquare.Left, BRsquare.Bottom); p.AddLine(BRsquare.Left - 1, BRsquare.Bottom, BLsquare.Right + 1, BLsquare.Bottom); if (corners.HasFlag(RectangleCorners.BottomLeft)) p.AddArc(BLarc, 90, 45); else p.AddLine(BLsquare.Right, BLsquare.Bottom, BLsquare.Left, BLsquare.Bottom); } return p; } public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners c, WhichHalf which_half) { return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c, which_half); } public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners c) { return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c, WhichHalf.Both); } public static GraphicsPath Create(Rectangle rect, int radius) { return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, RectangleCorners.All, WhichHalf.Both); } } 

}

上面的所有内容都适用于绘图,但如果你想将你的图形路径转换为自定义控件的区域,我认为你应该使用CreateRoundRectRgn函数(来自gdi32)来获得右上角,左下角和右下角的正确曲线(左上角已经过了根据半径正确绘制)。 快速浏览http://pages.citebite.com/e1u2t5b7t4bih (来自instanceofTom的答案的网站)

首先绘制四条线,并在四个角绘制弧线。