Нарисуйте закругленные прямоугольники в C#
Библиотека GDI + предоставляет множество методов для рисования фигур, таких как прямоугольники, эллипсы, линии и дуги. К сожалению, он не обеспечивает метод рисования прямоугольников с закругленными углами. Вы можете использовать ручку с атрибутом LineJoin, установленным в Rounded, но это слегка округляет углы.
В этом примере определяется следующий метод MakeRoundedRect. Он возвращает объект GraphicsPath, представляющий строки и дуги, необходимые для рисования прямоугольника с закругленными углами. Параметры позволяют определить, какие углы округлены и на сколько.
private GraphicsPath MakeRoundedRect( RectangleF rect, float xradius, float yradius, bool round_ul, bool round_ur, bool round_lr, bool round_ll) { PointF point1, point2; GraphicsPath path = new GraphicsPath(); 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); if (round_ur) point2 = new PointF(rect.Right - xradius, rect.Y); else point2 = new PointF(rect.Right, rect.Y); path.AddLine(point1, point2); 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); if (round_lr) point2 = new PointF(rect.Right, rect.Bottom - yradius); else point2 = new PointF(rect.Right, rect.Bottom); path.AddLine(point1, point2); 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); if (round_ll) point2 = new PointF(rect.X + xradius, rect.Bottom); else point2 = new PointF(rect.X, rect.Bottom); path.AddLine(point1, point2); 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); if (round_ul) point2 = new PointF(rect.X, rect.Y + yradius); else point2 = new PointF(rect.X, rect.Y); path.AddLine(point1, point2); path.CloseFigure(); return path; }
Метод создает GraphicsPath, а затем добавляет к нему дуги и строки. Основной подход - повторить два шага четыре раза.
В шаге 1 код рисует верхний левый угол прямоугольника. Метод определяет, должен ли он округлить верхний левый угол прямоугольника. Если это так, код добавляет дугу, представляющую этот угол, и устанавливает point1 в положение, в котором заканчивается дуга. Это точка, где должна начинаться верхняя сторона прямоугольника.
Если код не должен находиться в верхнем левом углу, код устанавливает point1 в верхний левый угол прямоугольника. Это позиция, в которой верхняя сторона прямоугольника должна начинаться, если угол не закруглен.
На шаге 2 код рисует верхнюю сторону прямоугольника. Для этого он определяет, следует ли округлить верхний правый угол и установить point2 соответствующим образом. Затем он добавляет строку, соединяющую point1 и point2 с GraphicsPath.
Метод повторяет эти два шага для других трех углов прямоугольника и возвращает GraphicsPath.
Следующий код показывает, как обработчик событий PaintBox Paint использует метод MakeRoundedRect для рисования верхнего округленного прямоугольника.
const float xradius = 20; const float yradius = 20; // Верхний прямоугольник. const float margin = 10; float hgt = (picSamples.ClientSize.Height - 3 * margin) / 2f; RectangleF rect = new RectangleF( margin, margin, picSamples.ClientSize.Width - 2 * margin, hgt); 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); }