Draw rounded rectangles in C#

[rounded rectangles]

The GDI+ library provides lots of methods for drawing shapes such as rectangles, ellipses, lines, and arcs. Unfortunately it doesn’t provide a method for drawing rectangles with rounded corners. You can use a pen with LineJoin property set to Rounded but that only rounds the corners slightly.

This example defines the following MakeRoundedRect method. It returns a GraphicsPath object representing the lines and arcs needed to draw a rectangle with rounded corners. Parameters let you determine which corners are rounded and by how much.

// Draw a rectangle in the indicated Rectangle
// rounding the indicated corners.
private GraphicsPath MakeRoundedRect(
    RectangleF rect, float xradius, float yradius,
    bool round_ul, bool round_ur, bool round_lr, bool round_ll)
    // Make a GraphicsPath to draw the rectangle.
    PointF point1, point2;
    GraphicsPath path = new GraphicsPath();

    // Upper left corner.
    if (round_ul)
        RectangleF corner = new RectangleF(
            rect.X, rect.Y,
            2 * xradius, 2 * yradius);
        path.AddArc(corner, 180, 90);
        point1 = new PointF(rect.X + xradius, rect.Y);
    else point1 = new PointF(rect.X, rect.Y);

    // Top side.
    if (round_ur)
        point2 = new PointF(rect.Right - xradius, rect.Y);
        point2 = new PointF(rect.Right, rect.Y);
    path.AddLine(point1, point2);

    // Upper right corner.
    if (round_ur)
        RectangleF corner = new RectangleF(
            rect.Right - 2 * xradius, rect.Y,
            2 * xradius, 2 * yradius);
        path.AddArc(corner, 270, 90);
        point1 = new PointF(rect.Right, rect.Y + yradius);
    else point1 = new PointF(rect.Right, rect.Y);

    // Right side.
    if (round_lr)
        point2 = new PointF(rect.Right, rect.Bottom - yradius);
        point2 = new PointF(rect.Right, rect.Bottom);
    path.AddLine(point1, point2);

    // Lower right corner.
    if (round_lr)
        RectangleF corner = new RectangleF(
            rect.Right - 2 * xradius,
            rect.Bottom - 2 * yradius,
            2 * xradius, 2 * yradius);
        path.AddArc(corner, 0, 90);
        point1 = new PointF(rect.Right - xradius, rect.Bottom);
    else point1 = new PointF(rect.Right, rect.Bottom);

    // Bottom side.
    if (round_ll)
        point2 = new PointF(rect.X + xradius, rect.Bottom);
        point2 = new PointF(rect.X, rect.Bottom);
    path.AddLine(point1, point2);

    // Lower left corner.
    if (round_ll)
        RectangleF corner = new RectangleF(
            rect.X, rect.Bottom - 2 * yradius,
            2 * xradius, 2 * yradius);
        path.AddArc(corner, 90, 90);
        point1 = new PointF(rect.X, rect.Bottom - yradius);
    else point1 = new PointF(rect.X, rect.Bottom);

    // Left side.
    if (round_ul)
        point2 = new PointF(rect.X, rect.Y + yradius);
        point2 = new PointF(rect.X, rect.Y);
    path.AddLine(point1, point2);

    // Join with the start point.

    return path;

The method creates a GraphicsPath and then adds arcs and lines to it. The basic approach is to repeat two steps four times.

In step 1, the code draws the rectangle’s upper left corner. The method determines whether it should round the rectangle’s upper left corner. If it should do so, the code adds an arc representing that corner and sets point1 to the position where the arc ends. That point is where the top side of the rectangle should begin.

If the code should not round the upper left corner, the code sets point1 to the rectangle’s upper left corner. That’s the position where the rectangle’s top side should begin if the corner isn’t rounded.

In step 2, the code draws the rectangle’s top side. To do that, it determines whether the upper right corner should be rounded and sets point2 appropriately. It then adds a line connecting point1 and point2 to the GraphicsPath.

The method repeats those two steps for the rectangle’s other three corners and returns the GraphicsPath.

The following code shows how the PictureBox control’s Paint event handler uses the MakeRoundedRect method to draw the top rounded rectangle.

const float xradius = 20;
const float yradius = 20;

// Top rectangle.
const float margin = 10;
float hgt = (picSamples.ClientSize.Height - 3 * margin) / 2f;
RectangleF rect = new RectangleF(
    margin, margin,
    picSamples.ClientSize.Width - 2 * margin,
using (Pen pen = new Pen(Color.Green, 5))
    GraphicsPath path = MakeRoundedRect(
        rect, xradius, yradius, true, true, true, true);
    e.Graphics.FillPath(Brushes.LightGreen, path);
    e.Graphics.DrawPath(pen, path);

This code creates a destination Rectangle and passes it and some other parameters into the MakeRoundedRect method. It then fills and draws the returned GraphicsPath.

Download Example   Follow me on Twitter   RSS feed   Donate

About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in drawing, graphics and tagged , , , , , , , , . Bookmark the permalink.

11 Responses to Draw rounded rectangles in C#

  1. Pingback: Display battery status in a friendly way in C# - C# HelperC# Helper

  2. Mark Dresser says:

    This worked excellently. I changed the inputs to match my project and now have a clean working RRect.

  3. Pingback: Make an image with rounded corners and a transparent background in C# - C# HelperC# Helper

  4. Pingback: Make a Pinterest-style diagonal picture montage in C# - C# HelperC# Helper

  5. Rotimi Omonusi says:

    Nice code. But I am having serious problem in applying it. It’s quite complicated. Do I have to create a class then add this method? If that’s the case, how do I use the custom controls in my form? Your explanation will be very much appreciated. Thanks

    • RodStephens says:

      Yes it is fairly complicated. And yes, all methods must be in classes in C#. You can add it to the form’s code if you like.

      You’ll also need to add the following statement at the top of the file that contains the method.

          using System.Drawing.Drawing2D;

      You may want to download the example program to see how it works.

  6. Hi RodStephens,
    Thanks for such a useful blog,
    Can we paint Flow chart diagram using C# paint?
    like diamond,circle , rounded rectangle etc.
    Please concern for the same .

    • RodStephens says:

      You should be able to use these shapes to draw a flow chart. You might also want to use the following example to draw diamonds and other shapes with rounded corners.

      Connect two line segments with a circular arc in C#

      Unfortunately building a general tool for creating flow charts is quite hard. If I were you, I would just use Word’s drawing tools or some other tool to do it rather than building a program to do it. Unless you have particularly simple needs.

  7. George says:

    Thanks it worked perfectly and i undertood more about GraphicsPath

  8. Timon says:

    Everything works fine, but there is a problem, how can I redraw this rectangle while the program is running?

    • RodStephens says:

      The MakeRoundedRect method makes a GraphcisPath representing the rounded rectangle. Your code needs to draw it.

      The example does that in the PictureBox’s Paint event handler. The PictureBox’s Resize event handler also refreshes the control, so it redraws the rectangles for the control’s new size.

      You could draw on a bitmap and display the result if you prefer.

      If that doesn’t answer your question, give me some more detail about what you want to do.

Comments are closed.