|
its a good solution as i was looking for it and it's work perfect in my project.
Thanks.
|
|
|
|
|
|
It is exactly what I am looking for. Thanks!
|
|
|
|
|
I think the code has errors in calculations corner radiuses in DRAW and FILL methods. I started to think so when I tried to fill using FILL method the inner region of my rounded rectangle previously marked by the DRAW method. I got or unfilled pieces of inner space or pieces double painted by DRAW and FILL methods - it can be seen if use transparent colors and use the same radius for DRAW and FILL methods.
|
|
|
|
|
I would love to help clean out the code above but in case you are using C# 3.0 onwards, I would suggest you take a look at Extended Graphics II [^] for a better alternative.
If there is something not correct there, please let me know.
Cheers,
Arun
The beginning of knowledge is the fear of God
|
|
|
|
|
|
Great Piece of Code....!
Thanks... 
|
|
|
|
|
I was going to write an article on doing this with extension methods but i'll add it here instead as i'm really just taking this code and modifying it slightly
public static void DrawRoundedRectangle(this Graphics g, Pen pen, Rectangle rect, int radius)
{
g.DrawRoundedRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height, radius);
}
public static void DrawRoundedRectangle(this Graphics g, 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);
g.DrawRoundRectangle(pen, fx, fy, fwidth, fheight, fradius);
}
public static void DrawRoundRectangle(this Graphics g, Pen pen, float x, float y, float width, float height, float radius)
{
RectangleF rectangle = new RectangleF(x, y, width, height);
GraphicsPath path = g.GetRoundedRect(rectangle, radius);
g.DrawPath(pen, path);
}
private static GraphicsPath GetRoundedRect(this Graphics g, RectangleF baseRect, float radius)
{
if (radius <= 0.0F)
{
GraphicsPath mPath = new GraphicsPath();
mPath.AddRectangle(baseRect);
mPath.CloseFigure();
return mPath;
}
if (radius >= (Math.Min(baseRect.Width, baseRect.Height)) / 2.0)
return g.GetCapsule(baseRect);
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();
path.AddArc(arc, 180, 90);
arc.X = baseRect.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = baseRect.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = baseRect.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
public static GraphicsPath GetCapsule(this Graphics g, RectangleF baseRect)
{
float diameter;
RectangleF arc;
GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
try
{
if (baseRect.Width > baseRect.Height)
{
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)
{
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);
}
else
{
path.AddEllipse(baseRect);
}
}
catch (Exception ex)
{
path.AddEllipse(baseRect);
}
finally
{
path.CloseFigure();
}
return path;
}
By using extension methods you don't need to derive a new type, and it will apply to all Graphics objects used in your project.
|
|
|
|
|
I debated about converting this code for Extension Methods but finally left this code as is for people who do not yet use newer version of the .Net Framework. However, I created a new article here[^] to demonstrate the power of Extension Methods with this code.
It works like a charm as you said and much of the hassle of creating and maintaining inherited objects is long gone. Ah, the relief!
Thanks for the comment even though it took me an year to reply to it.
Cheers,
Arun
The beginning of knowledge is the fear of God
|
|
|
|
|
I'm looking for a long time how I can make rounded corners rectangle, I'm happy, I finally found it.
my need in it is, I created a SplashScreen (my project is in vb, I'm using your class as dll) which it's BackgroundImage is set to some image.
I want the rectangle to be in the same size at the form, then fill the rectangle with the Form.Background image; set properties Form.BackColor and Form.TransparencyKey to the same color, and then, move all the labels to the foreground of the form, oops a wonderful splash screen.
if u use Visual Studio 2008, please observe it's splash screen, it has also a cool shadow which I don't know how to do, but let's forget this thing for right now.
Shimi)
Shimi
|
|
|
|
|
Hi!
Why you create new ExtendedGraphics class, just only for RoundRectangle drawing?
Stock Graphics has DrawPath and FillPath. It is ALL YOU NEED!
So, my example:
<br />
public class ExtendedPrimitives<br />
{<br />
<br />
public static GraphicsPath RoundRect(int x, int y,<br />
int width, int height,<br />
int radius, int lw)<br />
<br />
{<br />
GraphicsPath g = new GraphicsPath();<br />
int diameter = radius*2;<br />
g.AddArc(x+lw,y,diameter,diameter,180,90);<br />
g.AddArc(x+(width-diameter-lw),y,diameter,diameter,270,90);<br />
g.AddArc(x+(width-diameter-lw),y+(height-diameter-lw),<br />
diameter,diameter,360,90);<br />
g.AddArc(x+lw,y+(height-diameter-lw),diameter,diameter,90,90);<br />
g.CloseFigure();<br />
return g;<br />
<br />
}<br />
<br />
}
We have an ideal rounded rectangle
So, draw it:
<br />
GraphicsPath rrect = ExtendedPrimitives.RoundRect(100,100,100,130,3);<br />
g.DrawPath(new Pen(System.Drawing.Color.Navy,3),rrect);<br />
<br />
|
|
|
|
|
kzerza wrote: Stock Graphics has DrawPath and FillPath. It is ALL YOU NEED!
Nice example -
I just needed something basic like this
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Rectangle baseRect = base.ClientRectangle;
float radius = 14;
System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
gp.StartFigure();
gp.AddArc(baseRect.X, baseRect.Y, radius, radius, 180, 90);
gp.AddArc(baseRect.X + baseRect.Width - radius, baseRect.Y, radius, radius, 270, 90);
gp.AddArc(baseRect.X + baseRect.Width - radius, baseRect.Y + baseRect.Height - radius, radius, radius, 0, 90);
gp.AddArc(baseRect.X, baseRect.Y + baseRect.Height - radius, radius, radius, 90, 90);
gp.CloseFigure();
pe.Graphics.DrawPath(new Pen(Color.Blue), gp);
gp.Dispose();
}
|
|
|
|
|
My efforts have been largely focused towards keeping the code manageable and completely eliminating the need for a sub-class. Check out my updated instalment for the above code that requires you to extend or inherit nothing and just use the System.Drawing.Graphics class to do your work.
The updated instalment: Extended Graphics II [^]
Cheers,
Arun
The beginning of knowledge is the fear of God
|
|
|
|
|
|
Is it only me? Anyway, the rectangle isn't perfect. The only one top-left corner is good, otheres are not close enough to the rounded corners.
Any ideas?
Leo
|
|
|
|
|
I have the same question!!
How doesn't anybody reply this question?
James Jan
|
|
|
|
|
it's AddArc's fault..
after adding first arc you have to increase arc's diameter..
<br />
int corner = 20;<br />
GraphicsPath path = new GraphicsPath();<br />
Rectangle rectHelper = new Rectangle(0, 0, corner, corner);<br />
path.AddArc(rectHelper, 180, 90);<br />
<br />
corner++;<br />
rectHelper.Size = new Size(corner, corner);<br />
rectHelper.X = bounds.Width - corner-1;<br />
path.AddArc(rectHelper, 270, 90);<br />
<br />
rectHelper.Y = bounds.Height - corner-1;<br />
path.AddArc(rectHelper, 0, 90);<br />
<br />
rectHelper.X = 0;<br />
path.AddArc(rectHelper, 90, 90);<br />
<br />
path.CloseFigure();
life is study!!!
|
|
|
|
|
Hi,
I googled my name to find a piece of old code I had written awhile back and found this article. Very nice! Thanks for mentioning my name. It's nice to see somebody found my code useful and made something more out of it. Keep up the good work.
Tim Overbay
|
|
|
|
|
You're welcome Tim. For months, I had been trying to update and include new functionality into this class but don't have enough time to do so. Would you be more than willing to do so here? Thanks anyways for dropping by.
The beginning of knowledge is the fear of God
|
|
|
|
|
because that bug for exemple at radius 1.7F ...
<br />
private GraphicsPath GetRoundedRect(RectangleF baseRect, float radius) <br />
{<br />
if( radius<=0.0F ) <br />
{ <br />
GraphicsPath mPath = new GraphicsPath(); <br />
mPath.AddRectangle(baseRect); <br />
mPath.CloseFigure(); <br />
return mPath;<br />
}<br />
<br />
if( radius>=(Math.Min(baseRect.Width, baseRect.Height))/2.0) <br />
return GetCapsule( baseRect ); <br />
<br />
<br />
GraphicsPath gp = new GraphicsPath();<br />
gp.StartFigure();<br />
gp.AddArc(baseRect.X, baseRect.Y, radius, radius, 180, 90);<br />
gp.AddArc(baseRect.X + baseRect.Width - radius, baseRect.Y, radius, radius, 270, 90);<br />
gp.AddArc(baseRect.X + baseRect.Width - radius, baseRect.Y + baseRect.Height - radius, radius, radius, 0, 90);<br />
gp.AddArc(baseRect.X, baseRect.Y + baseRect.Height - radius, radius, radius, 90, 90);<br />
gp.CloseFigure();<br />
return gp;<br />
} <br />
|
|
|
|
|
Hi,
I just wanted to test your code but what is
return GetCapsule( baseRect );
Is there something missing?
|
|
|
|
|
Thanks Gooom!!!! Fixed issue going on in my app. and thanks Arun for the article!
|
|
|
|
|
public static GraphicsPath GetRoundedRect(RectangleF baseRect, float radiusX, float radiusY)
{
if (radiusX <= 0.0F)
{
GraphicsPath mPath = new GraphicsPath();
mPath.AddRectangle(baseRect);
mPath.CloseFigure();
return mPath;
}
if (radiusX >= (Math.Min(baseRect.Width, baseRect.Height)) / 2.0)
return GetCapsule(baseRect);
GraphicsPath gp = new GraphicsPath();
gp.StartFigure();
gp.AddArc(baseRect.X, baseRect.Y, radiusX, radiusY, 180, 90);
gp.AddArc(baseRect.X + baseRect.Width - radiusX, baseRect.Y, radiusX, radiusY, 270, 90);
gp.AddArc(baseRect.X + baseRect.Width - radiusX, baseRect.Y + baseRect.Height - radiusY, radiusX, radiusY, 0, 90);
gp.AddArc(baseRect.X, baseRect.Y + baseRect.Height - radiusY, radiusX, radiusY, 90, 90);
gp.CloseFigure();
return gp;
}
|
|
|
|
|
Fixed:
* AddArc needs diameter, not radius
* missing GetCapsule (turns out we don't need it)
* X and Y components work properly
public static GraphicsPath GetRoundedRect(RectangleF r, float radiusX, float radiusY)
{
GraphicsPath gp = new GraphicsPath();
gp.StartFigure();
if (radiusX <= 0.0F || radiusY <= 0.0F) {
gp.AddRectangle(r);
} else {
PointF d = new PointF(Math.Min(radiusX * 2, r.Width)
, Math.Min(radiusY * 2, r.Height));
gp.AddArc(r.X, r.Y, d.X, d.Y, 180, 90);
gp.AddArc(r.Right - d.X, r.Y, d.X, d.Y, 270, 90);
gp.AddArc(r.Right - d.X, r.Bottom - d.Y, d.X, d.Y, 0, 90);
gp.AddArc(r.X, r.Bottom - d.Y, d.X, d.Y, 90, 90);
}
gp.CloseFigure();
return gp;
}
|
|
|
|
|
Best example yet... thanks..
Here it is for you old school C++ folks:
static __inline void GenerateRoundedRectangle(GraphicsPath& gp, const RectF& rc, float flRadX, float flRadY){
gp.StartFigure();
if(flRadX <= 0.0f || flRadY <= 0.0f){
gp.AddRectangle(rc);
}else{
const PointF d(__min(flRadX * 2.0f, rc.Width), __min(flRadY * 2.0f, rc.Height));
gp.AddArc(rc.X, rc.Y, d.X, d.Y, 180.0f, 90.0f);
gp.AddArc(rc.GetRight() - d.X, rc.Y, d.X, d.Y, 270.0f, 90.0f);
gp.AddArc(rc.GetRight() - d.X, rc.GetBottom() - d.Y, d.X, d.Y, 0.0f, 90.0f);
gp.AddArc(rc.X, rc.GetBottom() - d.Y, d.X, d.Y, 90.0f, 90.0f);
}
gp.CloseFigure();
}
|
|
|
|
|