Нарисуйте закругленные прямоугольники в 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);
}
