How to Draw a Rounded Rectangle with WinForms (.NET)?

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#


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# - 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...


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.

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

}

}

Tags:

C#

.Net

Winforms