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

时间:2023-02-10 00:04:02

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#绘制矩形,我需要在每个边缘绘制弧线,首先绘制矩形,然后我需要单击按钮它将在边缘绘制弧线,我该怎么办?

5 个解决方案

#1


22  

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 Riggs offer 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

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,以便我们可以开始向路径添加边。此代码的其余部分用于左上角和圆角矩形的顶行。如果我们应该使这个角落圆角,我们添加一个弧 - 否则......

#2


18  

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#

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

#3


1  

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:

设置窗口区域以及创建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);

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

}

}

#4


0  

Everything above works for drawing but if you want to convert your graphics path to custom control's region i think you should use CreateRoundRectRgn function (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的答案的网站)

#5


0  

First draw the four lines, and draw arcs at the 4 corners.

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

#1


22  

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 Riggs offer 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

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,以便我们可以开始向路径添加边。此代码的其余部分用于左上角和圆角矩形的顶行。如果我们应该使这个角落圆角,我们添加一个弧 - 否则......

#2


18  

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#

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

#3


1  

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:

设置窗口区域以及创建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);

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

}

}

#4


0  

Everything above works for drawing but if you want to convert your graphics path to custom control's region i think you should use CreateRoundRectRgn function (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的答案的网站)

#5


0  

First draw the four lines, and draw arcs at the 4 corners.

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