Как нарисовать скругленный прямоугольник с WinForms (.NET)?
Рисуем прямоугольник, используя C#, и мне нужно нарисовать дугу по каждому ребру. Сначала я рисую прямоугольник, а затем мне нужно нажать кнопку, чтобы нарисовать дугу по краям, как я могу это сделать?
5 ответов
Графический класс в C# не имеет встроенного метода для рисования прямоугольников со скругленными углами, однако есть несколько способов добиться этого эффекта. Ссылки в ответе Джей Риггса предлагают хорошие предложения о том, с чего начать, кроме того, я бы посоветовал вам ознакомиться с этой статьей:
C# - Создание скругленных прямоугольников с использованием графического пути
Итак, сначала мы создаем GraphicsPath, а затем вызываем StartFigure, чтобы мы могли начать добавлять ребра в путь. Остальная часть этого кода предназначена для верхнего левого угла и верхней линии скругленного прямоугольника. Если мы должны сделать этот угол закругленным, мы добавим дугу - иначе...
Рисовать прямоугольник с закругленными углами?
Пытаться:
Расширенная графика - скругленные прямоугольники, метрики шрифта и многое другое для C# 3.0
Расширенная графика - реализация Rounded Rectangle в C#
Я знаю, что этот пост старый, но он наиболее популярен при поиске того, как делать скругленные прямоугольники в C#, и у меня были некоторые проблемы с ним. Метод AddArc является неточным, и поэтому, если вы используете код из принятого ответа, вы получите необычный прямоугольник с закругленными углами. Верхний левый угол правильный, верхний правый и нижний левый деформированы, а нижний правый слишком мал. Я исправил некоторые вещи в коде, чтобы компенсировать неточности AddArc, и я считаю, что у меня есть рабочее решение для создания правильного скругленного прямоугольника. Эта версия также может разделять прямоугольник на верхнюю левую половину и нижнюю правую половину, что удобно для создания светлых / темных теней для эффекта 3d.
Пример использования для установки области окна, а также создания верхних / нижних путей для трассировки светлыми и темными ручками для затенения:
Region = new Region(RoundedRectangles.RoundedRectangle.Create(new Rectangle(0, 0, Size.Width, Size.Height), 8, RoundedRectangles.RoundedRectangle.RectangleCorners.TopRight | RoundedRectangles.RoundedRectangle.RectangleCorners.TopLeft));
TopLeftPath = RoundedRectangles.RoundedRectangle.Create(new Rectangle(0, 0, Size.Width, Size.Height), 8, RoundedRectangles.RoundedRectangle.RectangleCorners.TopRight | RoundedRectangles.RoundedRectangle.RectangleCorners.TopLeft, RoundedRectangles.RoundedRectangle.WhichHalf.TopLeft);
BottomRightPath = RoundedRectangles.RoundedRectangle.Create(new Rectangle(0, 0, Size.Width-1, Size.Height-1), 8, RoundedRectangles.RoundedRectangle.RectangleCorners.TopRight | RoundedRectangles.RoundedRectangle.RectangleCorners.TopLeft, RoundedRectangles.RoundedRectangle.WhichHalf.BottomRight);
И, наконец, код:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace RoundedRectangles
{
public abstract class RoundedRectangle
{
[Flags]
public enum RectangleCorners
{
None = 0, TopLeft = 1, TopRight = 2, BottomLeft = 4, BottomRight = 8,
All = TopLeft | TopRight | BottomLeft | BottomRight
}
public enum WhichHalf
{
TopLeft,
BottomRight,
Both
}
static void Corner(GraphicsPath path, int x1, int y1, int x2, int y2, int x3, int y3)
{
path.AddLine(x1, y1, x2, y2);
path.AddLine(x2, y2, x3, y3);
}
public static GraphicsPath Create(int x, int y, int width, int height, int radius, RectangleCorners corners, WhichHalf half)
{
if (radius <= 0)
{
GraphicsPath rectp = new GraphicsPath();
rectp.AddRectangle(new Rectangle(x, y, width, height));
return rectp;
}
int dia = radius * 2;
Rectangle TLarc = new Rectangle(x, y, dia, dia);
Rectangle TRarc = new Rectangle(x + width - dia - 1, y, dia, dia);
Rectangle BRarc = new Rectangle(x + width - dia - 1, y + height - dia - 1, dia, dia);
Rectangle BLarc = new Rectangle(x, y + height - dia - 1, dia, dia);
Rectangle TLsquare = new Rectangle(x, y, radius, radius);
Rectangle TRsquare = new Rectangle(x + width - radius, y, radius, radius);
Rectangle BRsquare = new Rectangle(x + width - radius, y + height - radius, radius, radius);
Rectangle BLsquare = new Rectangle(x, y + height - radius, radius, radius);
GraphicsPath p = new GraphicsPath();
p.StartFigure();
if (half == WhichHalf.Both || half == WhichHalf.TopLeft)
{
if (corners.HasFlag(RectangleCorners.BottomLeft))
p.AddArc(BLarc, 135, 45);
else
p.AddLine(BLsquare.Left, BLsquare.Bottom, BLsquare.Left, BLsquare.Top);
p.AddLine(BLsquare.Left, BLsquare.Top - 1, TLsquare.Left, TLsquare.Bottom + 1);
if (corners.HasFlag(RectangleCorners.TopLeft))
p.AddArc(TLarc, 180, 90);
else
Corner(p, TLsquare.Left, TLsquare.Bottom, TLsquare.Left, TLsquare.Top, TLsquare.Right, TLsquare.Top);
p.AddLine(TLsquare.Right + 1, TLsquare.Top, TRsquare.Left - 1, TRsquare.Top);
if (corners.HasFlag(RectangleCorners.TopRight))
p.AddArc(TRarc, -90, 45);
}
if (half == WhichHalf.Both || half == WhichHalf.BottomRight)
{
if (corners.HasFlag(RectangleCorners.TopRight))
p.AddArc(TRarc, -45, 45);
else
p.AddLine(TRsquare.Right, TRsquare.Top, TRsquare.Right, TRsquare.Bottom);
p.AddLine(TRsquare.Right, TRsquare.Bottom + 1, BRsquare.Right, BRsquare.Top - 1);
if (corners.HasFlag(RectangleCorners.BottomRight))
p.AddArc(BRarc, 0, 90);
else
Corner(p, BRsquare.Right, BRsquare.Top, BRsquare.Right, BRsquare.Bottom, BRsquare.Left, BRsquare.Bottom);
p.AddLine(BRsquare.Left - 1, BRsquare.Bottom, BLsquare.Right + 1, BLsquare.Bottom);
if (corners.HasFlag(RectangleCorners.BottomLeft))
p.AddArc(BLarc, 90, 45);
else
p.AddLine(BLsquare.Right, BLsquare.Bottom, BLsquare.Left, BLsquare.Bottom);
}
return p;
}
public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners c, WhichHalf which_half)
{ return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c, which_half); }
public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners c)
{ return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c, WhichHalf.Both); }
public static GraphicsPath Create(Rectangle rect, int radius)
{ return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, RectangleCorners.All, WhichHalf.Both); }
}
}
Используйте свойство LineJoin Pen
Pen myPen = new Pen(Brushes.Black);
myPen.Width = 8.0f;
// Set the LineJoin property
myPen.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
// Draw the rectangle
e.Graphics.DrawRectangle(myPen, new Rectangle(50, 50, 200, 200));
Все вышеперечисленное работает для рисования, но если вы хотите преобразовать свой графический путь в область пользовательского элемента управления, я думаю, что вы должны использовать функцию CreateRoundRectRgn (из gdi32) для правильной кривой для верхнего правого, нижнего левого и нижнего правого краев (верхний левый край был нарисовано правильно по радиусу). Взгляните на http://pages.citebite.com/e1u2t5b7t4bih (сайт из ответа instanceofTom)