Ali Tor Ali Tor - 1 month ago 21
C# Question

How to draw a circular progressbar pie using GraphicsPath in WinForm?

I want my custom circular progress bar in WinForm. But the result doesnt fit to what I think. How can I draw the shape as the same in this picture?. I uploaded two image to be clear in my problem.

Target shape

My code result

My code to do this:

void Form1_Paint(object sender, PaintEventArgs e)
{
int angle = 120;

e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

Rectangle outerRect = new Rectangle(50, 50, 100, 100);
Rectangle innerRect = new Rectangle(70, 70, 60, 60);

int innerRadius = innerRect.Width / 2;
int outerRadius = outerRect.Width / 2;

Point innerCenter = new Point(innerRect.X + innerRadius, innerRect.Y + innerRadius);
Point outerCenter = new Point(outerRect.X + outerRadius, outerRect.Y + outerRadius);

GraphicsPath outerCircle = new GraphicsPath();
outerCircle.AddEllipse(outerRect);

GraphicsPath innerCircle = new GraphicsPath();
innerCircle.AddEllipse(innerRect);

GraphicsPath progPath = new GraphicsPath();

Point p1 = new Point(outerRect.X + outerRadius, outerRect.Y);
Point p2 = new Point(innerRect.X + innerRadius, innerRect.Y);


Point inner = new Point((int)(innerRadius * Math.Cos(angle * Math.PI / 180) + innerCenter.X),
(int)(innerRadius * Math.Sin(angle * Math.PI / 180) + innerCenter.Y));
Point outer = new Point((int)(outerRadius * Math.Cos(angle * Math.PI / 180) + outerCenter.X),
(int)(outerRadius * Math.Sin(angle * Math.PI / 180) + outerCenter.Y));

progPath.AddLine(p1, p2);
progPath.AddArc(innerRect, -90, angle);
progPath.AddLine(inner, outer);
progPath.AddArc(outerRect, angle - 90,-angle);

progPath.Widen(Pens.Black);
e.Graphics.DrawPath(Pens.Black, progPath);

}

Answer

You can create a GraphicsPath, then add 2 arcs to the path using AddArc method:

  • Outer arc from start angle 270 and sweep angle 120 degree.
  • Inner arc in opposite direction, from start angle 270 + 120 and sweep angle -120 degree
  • Then close the path using GraphicsPath.CloseFigure.

This way the you will have a thick arc as path.

You can fill the path, using Graphics.FillPath method. And also you can draw the borders using GraphicsPath.drawPath method.

Result

enter image description here

Code

private void Form1_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

    var center = new Point(100, 100);
    var innerR = 30;
    var thickness = 20;
    var startAngle = 270;
    var arcLength = 120;
    var outerR = innerR + thickness;
    var outerRect = new Rectangle
                    (center.X - outerR, center.Y - outerR, 2 * outerR, 2 * outerR);
    var innerRect = new Rectangle
                    (center.X - innerR, center.Y - innerR, 2 * innerR, 2 * innerR);

    using (var p = new GraphicsPath())
    {
        p.AddArc(outerRect, startAngle, arcLength);
        p.AddArc(innerRect, startAngle + arcLength, -arcLength);
        p.CloseFigure();
        e.Graphics.FillPath(Brushes.Green, p);
        e.Graphics.DrawPath(Pens.Black, p);
    }
}