C# 如何使用 WinForms (.NET) 绘制圆角矩形?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1967944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Draw a Rounded Rectangle with WinForms (.NET)?
提问by ratty
Draw rectangle using C# and I need to draw the arc in every edges first of all I draw rectangle and then I need click button it will draw the arc at edges, how can I do it?
使用 C# 绘制矩形,我需要首先在每个边缘绘制圆弧,然后我需要单击按钮,它将在边缘绘制圆弧,我该怎么做?
采纳答案by Tom Neyland
The graphics class in C# does not have a built-in method to draw rounded rectangles, however there are several ways that you can accomplish this affect. The links in the answer by Jay Riggsoffer good suggestions on where to start, additionally I would suggest that you check out this article:
C# 中的图形类没有绘制圆角矩形的内置方法,但是有多种方法可以实现这种效果。Jay Riggs的回答中的链接提供了关于从哪里开始的好建议,另外我建议您查看这篇文章:
C# - Creating Rounded Rectangles Using A Graphics Path
C# - 使用图形路径创建圆角矩形
So first, we create a GraphicsPath, and then we call StartFigure so that we can start adding edges to the path. The rest of this code is for the top left corner and the top line of the rounded rectangle. If we are supposed to make this corner rounded, we add an arc - otherwise...
所以首先,我们创建一个 GraphicsPath,然后我们调用 StartFigure 以便我们可以开始向路径添加边。此代码的其余部分用于圆角矩形的左上角和顶线。如果我们应该使这个角变圆,我们添加一个圆弧 - 否则......
回答by Benny
First draw the four lines, and draw arcs at the 4 corners.
先画四条线,在四个角画圆弧。
回答by Jay Riggs
Draw a rectangle with rounded corners?
画一个带圆角的矩形?
Try:
尝试:
Extended Graphics - Rounded rectangles, Font metrics and more for C# 3.0
Extended Graphics - An implementation of Rounded Rectangle in C#
回答by ozanmuyes
Everything above works for drawing but if you want to convert your graphics path to custom control's region i think you should use CreateRoundRectRgnfunction (from gdi32) for proper curve for top right, bottom left and bottom right edges (top left edge has been drawn correctly according to radius). Take a quick look at http://pages.citebite.com/e1u2t5b7t4bih(site from instanceofTom's answer)
以上所有内容都适用于绘图,但如果您想将图形路径转换为自定义控件的区域,我认为您应该使用CreateRoundRectRgn函数(来自 gdi32)为右上、左下和右下边缘(左上边缘已根据半径正确绘制)。快速浏览一下http://pages.citebite.com/e1u2t5b7t4bih(来自 instanceofTom 回答的站点)
回答by Jace Priester
I know this post is old, but it's the top hit when searching for how to do rounded rectangles in C# and I've had some problems with it. The AddArc method is inaccurate and as such if you use the code from the accepted answer you will get a funky rounded rectangle. The top left corner is correct, the top right and bottom left are misshapen, and the bottom right is too small. I have adjusted some things in the code to compensate for AddArc's inaccuracies and I believe I have a working solution for creating a proper rounded rectangle. This version can also separate the rectangle into top-left-half and bottom-right-half sections which is handy for doing light/dark shading for 3d effect.
我知道这篇文章很旧,但它是搜索如何在 C# 中制作圆角矩形时的热门话题,我遇到了一些问题。AddArc 方法不准确,因此如果您使用已接受答案中的代码,您将得到一个时髦的圆角矩形。左上角正确,右上角和左下角畸形,右下角太小。我已经调整了代码中的一些内容以补偿 AddArc 的不准确之处,并且我相信我有一个可行的解决方案来创建一个合适的圆角矩形。此版本还可以将矩形分成左上半部分和右下半部分,这对于为 3d 效果进行明/暗着色非常方便。
Example usage for setting a window region and also creating topleft/bottomright paths for tracing with light and dark pens for shading:
设置窗口区域以及创建左上/右下路径的示例用法,以使用明暗笔进行阴影跟踪:
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);
And finally the code:
最后是代码:
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); }
}
}
}
回答by Javed Iqbal
Use the LineJoin property of Pen
使用 Pen 的 LineJoin 属性
Pen myPen = new Pen(Brushes.Black);
myPen.Width = 8.0f;
// Set the LineJoin property
myPen.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
// Draw the rectangle
e.Graphics.DrawRectangle(myPen, new Rectangle(50, 50, 200, 200));