Click here to Skip to main content
13,046,533 members (72,023 online)
Click here to Skip to main content
Add your own
alternative version


86 bookmarked
Posted 13 Dec 2003

Extended Graphics - An implementation of Rounded Rectangle in C#

Rate this:
Please Sign up or sign in to vote.
An implementation of Rounded Rectangle in C# which could be used to create XP-like buttons and rounded border.


Devasted with hours of coding practices and hard-to-design Java applications, I was tempted to try the Microsoft .Net Framework and found C# as a better alternative to Java. Making Windows programs was even easier and I could see endless possibilities for programs on the Windows Platform.

After-effects of this switch left me wondering how I could create graphics on components and forms and I somehow (read: hours of searches on CodeProject and the Framework Documentation) came to the conclusion that the use of Graphics was a necessity in my programs. Meanwhile, CodeProject was flooding with articles on creating XP-like buttons and forms. More specifically, user controls that used rounded paths and ellaborate designs. That's when I decided that I would create a similar button with a Rounded Rectangle. "It's so simple", I thought to myself.


I sat down to create the button myself. Vague images, floated around in my head, of how I would have accomplished this in Java. The most appropriate implementation that I could think of was something like this (Oh! How I loved Java):

import java.awt.*;

// A simple implementation of a drawing with Rounded Rectangle in Java.
// Notice that the Graphics class has methods:
// fillRoundRect and drawRoundRect,
// both having six arguments, the last two being width 
// and height of the round
// curves or arcs.
public class RoundButton extends Canvas
    public RoundButton()
        // Initialization code comes here
        this.setSize(100, 20);

    public void paint(Graphics g)
        // Drawing code comes here
        g.setColor(new Color(200, 200, 200));
        g.fillRoundRect(2, 2, this.getWidth()-4,
          this.getHeight()-4, 5, 5);
        g.setColor(new Color(60, 60, 60));
        g.drawRoundRect(2, 2, this.getWidth()-4,
          this.getHeight()-4, 5, 5);

The Horror

However, as I stepped further to demonstrate the same effect in C#, it was then that I came face-to-face with sudden disbelief. The C# Graphics class that I had praised so much lacked a method for a Rounded Rectangle. What!?! How tedious would it be to create a Rounded Rectangle in such a situation. So, I retreated back to where I had started: searching CodeProject. Though, I found loads of code telling me how this could be implemented but all the codes were built around some user control or component. I wanted a class that would most probably inherit the methods and properties of the

class and include additional and extended functionality. But there was still one problem: The Graphics class was
and/or sealed (I don't know why I hate this word).

The Answers

Amidst results on Google [new window], I came across a forum named Drawing Rectangle but with rounded corners... [new window] that lay there, waiting for a desparate soul to encounter it's existence on the Mathew Reynold's .NET 247's Newsgroup [new window]. A certain person, whom I would like to mention here, named Tim Overbay, provided with a little routine to create such a Rounded Rectangle in VB.Net. This was just the starting point I had needed to carry on with my very own implementation. I copied the code, converted it to C# and there I had it. The final result: a class that I now lovingly dub as the ExtendedGraphics class. The complete code is present here as follows.

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 

// A simple extension to the Graphics class for extended 
// graphic routines, such, 
// as for creating rounded rectangles. 
// Because, Graphics class is an abstract class, 
// that is why it can not be inherited. Although, 
// I have provided a simple constructor 
// that builds the ExtendedGraphics object around a 
// previously created Graphics object. 
// Please contact: for the most 
// recent implementations of
// this class. 
namespace System.Drawing.Extended 

    /// <SUMMARY> 
    /// Inherited child for the class Graphics encapsulating 
    /// additional functionality for curves and rounded rectangles. 
    /// </SUMMARY> 
    public class ExtendedGraphics 

        private Graphics mGraphics; 
        public Graphics Graphics 
            get{ return this.mGraphics; } 
            set{ this.mGraphics = value; } 

        public ExtendedGraphics(Graphics graphics) 
            this.Graphics = graphics; 

        #region Fills a Rounded Rectangle with integers. 
        public void FillRoundRectangle(System.Drawing.Brush brush, 
          int x, int y,
          int width, int height, int radius) 

            float fx = Convert.ToSingle(x);
            float fy = Convert.ToSingle(y); 
            float fwidth = Convert.ToSingle(width);
            float fheight = Convert.ToSingle(height); 
            float fradius = Convert.ToSingle(radius); 
            this.FillRoundRectangle(brush, fx, fy, 
              fwidth, fheight, fradius); 


        #region Fills a Rounded Rectangle with continuous numbers.
        public void FillRoundRectangle(System.Drawing.Brush brush, 
          float x, float y,
          float width, float height, float radius)
            RectangleF rectangle = new RectangleF(x, y, width, height);
            GraphicsPath path = this.GetRoundedRect(rectangle, radius);
            this.Graphics.FillPath(brush, path);

        #region Draws a Rounded Rectangle border with integers. 
        public void DrawRoundRectangle(System.Drawing.Pen pen, int x, int y,
          int width, int height, int radius) 
            float fx = Convert.ToSingle(x);
            float fy = Convert.ToSingle(y); 
            float fwidth = Convert.ToSingle(width);
            float fheight = Convert.ToSingle(height); 
            float fradius = Convert.ToSingle(radius); 
            this.DrawRoundRectangle(pen, fx, fy, fwidth, fheight, fradius); 

        #region Draws a Rounded Rectangle border with continuous numbers. 
        public void DrawRoundRectangle(System.Drawing.Pen pen, 
          float x, float y,
          float width, float height, float radius) 
            RectangleF rectangle = new RectangleF(x, y, width, height); 
            GraphicsPath path = this.GetRoundedRect(rectangle, radius); 
            this.Graphics.DrawPath(pen, path); 

        #region Get the desired Rounded Rectangle path. 
        private GraphicsPath GetRoundedRect(RectangleF baseRect, 
           float radius) 
            // if corner radius is less than or equal to zero, 
            // return the original rectangle 
            if( radius<=0.0F ) 
                GraphicsPath mPath = new GraphicsPath(); 
                return mPath;

            // if the corner radius is greater than or equal to 
            // half the width, or height (whichever is shorter) 
            // then return a capsule instead of a lozenge 
            if( radius>=(Math.Min(baseRect.Width, baseRect.Height))/2.0) 
              return GetCapsule( baseRect ); 

            // create the arc for the rectangle sides and declare 
            // a graphics path object for the drawing 
            float diameter = radius * 2.0F; 
            SizeF sizeF = new SizeF( diameter, diameter );
            RectangleF arc = new RectangleF( baseRect.Location, sizeF ); 
            GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); 

            // top left arc 
            path.AddArc( arc, 180, 90 ); 

            // top right arc 
            arc.X = baseRect.Right-diameter; 
            path.AddArc( arc, 270, 90 ); 

            // bottom right arc 
            arc.Y = baseRect.Bottom-diameter; 
            path.AddArc( arc, 0, 90 ); 

            // bottom left arc
            arc.X = baseRect.Left;     
            path.AddArc( arc, 90, 90 );     

            return path; 

        #region Gets the desired Capsular path. 
        private GraphicsPath GetCapsule( RectangleF baseRect ) 
            float diameter; 
            RectangleF arc; 
            GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath(); 
                if( baseRect.Width>baseRect.Height ) 
                    // return horizontal capsule 
                    diameter = baseRect.Height; 
                    SizeF sizeF = new SizeF(diameter, diameter);
                    arc = new RectangleF( baseRect.Location, sizeF ); 
                    path.AddArc( arc, 90, 180); 
                    arc.X = baseRect.Right-diameter; 
                    path.AddArc( arc, 270, 180); 
                else if( baseRect.Width < baseRect.Height ) 
                    // return vertical capsule 
                    diameter = baseRect.Width;
                    SizeF sizeF = new SizeF(diameter, diameter);
                    arc = new RectangleF( baseRect.Location, sizeF ); 
                    path.AddArc( arc, 180, 180 ); 
                    arc.Y = baseRect.Bottom-diameter; 
                    path.AddArc( arc, 0, 180 ); 
                    // return circle 
                    path.AddEllipse( baseRect ); 
            catch(Exception ex)
                path.AddEllipse( baseRect ); 
            return path; 

What does the code do?

The above code is a simple class that could be used in your projects for additional drawing routines. What I tried to do here is that I created the class that accepts a Graphics class object. Why I did this is a harsher punishment I got because the Graphics class was sealed and it could not be inherited. Otherwise, I would have simply had inherited my class with the Graphics class.

There are two private methods in the class and four public methods. The two private methods namely the GetRoundedRect(...) and the GetCapsule(...) method are of the most importance. Both these methods draw four lines connected with rounded arcs to form a Rounded Rectangle. If the rectangle's height or width is less than the diameter of arc specified, then the method instead of providing the user with a rectangular shape, gives the user a capsule obtained through the GetCapsule(...) method. If both the width and height are less than the diameter or the arc and are of the same size, then a circular ellipse is obtained from the method.

To make the class more useful and familiar, four methods are added to the class that resemble methods found in the Graphics class.

What's Next...

Think of this article as a first in a series of articles, because I would be using this same class in some of my upcoming tutorials on how to create buttons and effective user interface. I would be grateful to anyone who gives me advice on how I could optimize the above code and any suggestions. I am working on an implementation for even-sided polygons and will include those snippets and methods in this class in the near future.


This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-ShareAlike 2.5 License


About the Author

Arun Reginald Zaheeruddin
Software Developer (Senior) Plasmoid Technologies
United Kingdom United Kingdom
Arun Reginald Zaheeruddin is a software developer residing in London. His initial forays into the world of software development began in December 1999 when he first got hooked to Java. He still prefers it over other programming languages. Also with a commercial experience of over eight years in C, C++, C#, Objective-C, VB.Net, Python, Ruby, PHP, HTML, Javascript and CSS, he feels it an honour to share his knowledge about the world of programming with people thinking of wading its waters. In his part time, he does laptop repairs at the Computer & Laptop Centre.

You may also be interested in...

Comments and Discussions

GeneralException Pin
Donec11-Oct-05 8:15
sussDonec11-Oct-05 8:15 
GeneralRe: Exception Pin
Arun Reginald12-Oct-05 13:49
memberArun Reginald12-Oct-05 13:49 
QuestionDoes this work in Web Forms ( Pin
Nicholas Furgiuele23-Mar-05 16:54
memberNicholas Furgiuele23-Mar-05 16:54 
AnswerRe: Does this work in Web Forms ( Pin
Jason Jakob10-Aug-05 11:50
sussJason Jakob10-Aug-05 11:50 
GeneralThanks and a question Pin
FinallyInSeattle20-Aug-04 13:04
memberFinallyInSeattle20-Aug-04 13:04 
GeneralI love your code Pin
SJ_Phoenix11-Jul-04 0:19
memberSJ_Phoenix11-Jul-04 0:19 
GeneralRe: I love your code Pin
Aaron Reginald11-Jul-04 10:49
memberAaron Reginald11-Jul-04 10:49 
Generalsimple rounded rectangle Pin
luckydon23-Dec-03 4:58
memberluckydon23-Dec-03 4:58 

i enjoyed the article and am also currently creating dynamic UI element libraries for my website.

i discovered a simple, two-step routine to create a rectangle or capsule button or concievably any convex polygon.

first stage is to define a graphics path and add an ellipse.
then, instead of filling the entire figure, fill an overlapping rectangle, whose corners fall between the ellipses bounding rectangle and the ellipses border.

remember, the path gradient does not fill outside its path.
if you play around with the geometry, you should get a nice rounded or capsule effect...

see Creating a Path Gradient in the GDI+ section of MSDN for more details.
Heres the sample code:

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

Et versus digitos habet.
GeneralRe: simple rounded rectangle(corrected code) Pin
luckydon23-Dec-03 5:08
memberluckydon23-Dec-03 5:08 lets you draw your graphics in Pin
Frank Hileman15-Dec-03 13:38
memberFrank Hileman15-Dec-03 13:38 
QuestionPet Shop? What Pet Shop? Pin
clintonG15-Dec-03 4:54
memberclintonG15-Dec-03 4:54 
AnswerRe: Pet Shop? What Pet Shop? Pin
Aaron Reginald16-Dec-03 2:10
memberAaron Reginald16-Dec-03 2:10 
GeneralRe: Pet Shop? What Pet Shop? Pin
Ianier Munoz13-Sep-04 21:09
memberIanier Munoz13-Sep-04 21:09 
GeneralRe: Pet Shop? What Pet Shop? Pin
Aaron Reginald16-Sep-04 10:25
memberAaron Reginald16-Sep-04 10:25 
QuestionScreenshot? Pin
Joel Holdsworth15-Dec-03 1:00
memberJoel Holdsworth15-Dec-03 1:00 
AnswerRe: Screenshot? Pin
Aaron Reginald15-Dec-03 22:52
memberAaron Reginald15-Dec-03 22:52 
QuestionDid you love the code? Pin
Aaron Reginald14-Dec-03 22:18
memberAaron Reginald14-Dec-03 22:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170713.1 | Last Updated 14 Dec 2003
Article Copyright 2003 by Arun Reginald Zaheeruddin
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid