Monday, January 12, 2004

To draw a rectangle with rounded corners is not a trivial task in Compact Framework due to lack of ability to draw arcs (Graphics.DrawArc, GraphicPaths in the big .NET, etc..). OK, so why don't we just use Graphics.DrawEllipse to draw a rounded corners instead? Definitelly we can do that, but we would have to somehow wipe out the internal arcs:

So, my solutuion to that problem is to create a poligon shape that would fill the rectangle with the required back color and would wipe out unneeded arcs:

public static void DrawRoundedRectangle(Graphics g, Pen p, Color backColor, Rectangle rc, Size size)
{
   Point[] points = new Point[8];
   
   //prepare points for poligon
   points[0].X = rc.Left + size.Width / 2;
   points[0].Y = rc.Top + 1;
   points[1].X = rc.Right - size.Width / 2;
   points[1].Y = rc.Top + 1;

   points[2].X =  rc.Right;
   points[2].Y = rc.Top + size.Height / 2;
   points[3].X =  rc.Right;
   points[3].Y = rc.Bottom - size.Height / 2;

   points[4].X =  rc.Right - size.Width / 2;
   points[4].Y = rc.Bottom;
   points[5].X =  rc.Left  + size.Width / 2;
   points[5].Y = rc.Bottom;

   points[6].X =  rc.Left + 1;
   points[6].Y = rc.Bottom - size.Height / 2;
   points[7].X =  rc.Left + 1;
   points[7].Y = rc.Top + size.Height / 2;

   //prepare brush for background
   Brush fillBrush = new SolidBrush(backColor);

   //draw side lines and circles in the corners
   g.DrawLine(p, rc.Left  + size.Width / 2, rc.Top,
    rc.Right - size.Width / 2, rc.Top);
   g.FillEllipse(fillBrush, rc.Right - size.Width, rc.Top,
    size.Width, size.Height);
   g.DrawEllipse(p, rc.Right - size.Width, rc.Top,
    size.Width, size.Height);

   g.DrawLine(p, rc.Right, rc.Top + size.Height / 2,
    rc.Right, rc.Bottom - size.Height / 2);
   g.FillEllipse(fillBrush, rc.Right - size.Width, rc.Bottom - size.Height,
    size.Width, size.Height);
   g.DrawEllipse(p, rc.Right - size.Width, rc.Bottom - size.Height,
    size.Width, size.Height);
   
   g.DrawLine(p, rc.Right - size.Width / 2, rc.Bottom,
    rc.Left  + size.Width / 2, rc.Bottom);
   g.FillEllipse(fillBrush, rc.Left, rc.Bottom - size.Height,
    size.Width, size.Height);
   g.DrawEllipse(p, rc.Left, rc.Bottom - size.Height,
    size.Width, size.Height);
   
   g.DrawLine(p, rc.Left, rc.Bottom - size.Height / 2,
    rc.Left, rc.Top + size.Height / 2);
   g.FillEllipse(fillBrush, rc.Left, rc.Top,
    size.Width, size.Height);
   g.DrawEllipse(p, rc.Left, rc.Top,
    size.Width, size.Height);
   
   //fill the background and remove the internal arcs  
      g.FillPolygon(fillBrush, points);
   //dispose the brush
   fillBrush.Dispose();
  }

And this is how you'd use this method:

Rectangle rc =  new Rectangle(10, 10, 100, 30);

DrawRoundedRectangle(e.Graphics,

new Pen(Color.Black), Color.CadetBlue, rc, new Size(8, 8));

 
1/12/2004 11:52:30 PM (GMT Standard Time, UTC+00:00)  #     |