Как создать скругленный прямоугольник во время выполнения в Windows Forms с VB.NET/C#? - PullRequest
6 голосов
/ 26 июня 2009

Мне бы хотелось создать закрашенный прямоугольник с закругленными углами во время выполнения и назначить его как содержимое PictureBox (уже созданного и скрытого) в Windows Forms.

У вас есть идея, как я могу это реализовать?

Ответы [ 3 ]

13 голосов
/ 16 марта 2011

Проблема с заливочным раствором, который отмечен как ответ, заключается в том, что он не очень хорошо работает с не сплошными / однородными кистями. Вот еще один, основанный на классе GraphicsPath, который, я думаю, более пригоден для повторного использования:

public static void FillRoundedRectangle(Graphics graphics, Rectangle rectangle, Brush brush, int radius)
{
    if (graphics == null)
        throw new ArgumentNullException("graphics");

    SmoothingMode mode = graphics.SmoothingMode;
    graphics.SmoothingMode = SmoothingMode.AntiAlias;

    using (GraphicsPath path = RoundedRectangle(rectangle, radius))
    {
        graphics.FillPath(brush, path);
    }
    graphics.SmoothingMode = mode;
}

public static GraphicsPath RoundedRectangle(Rectangle r, int radius)
{
    GraphicsPath path = new GraphicsPath();
    int d = radius * 2;

    path.AddLine(r.Left + d, r.Top, r.Right - d, r.Top);
    path.AddArc(Rectangle.FromLTRB(r.Right - d, r.Top, r.Right, r.Top + d), -90, 90);
    path.AddLine(r.Right, r.Top + d, r.Right, r.Bottom - d);
    path.AddArc(Rectangle.FromLTRB(r.Right - d, r.Bottom - d, r.Right, r.Bottom), 0, 90);
    path.AddLine(r.Right - d, r.Bottom, r.Left + d, r.Bottom);
    path.AddArc(Rectangle.FromLTRB(r.Left, r.Bottom - d, r.Left + d, r.Bottom), 90, 90);
    path.AddLine(r.Left, r.Bottom - d, r.Left, r.Top + d);
    path.AddArc(Rectangle.FromLTRB(r.Left, r.Top, r.Left + d, r.Top + d), 180, 90);
    path.CloseFigure();
    return path;
}

и вот код только Draw (не заполнение), основанный на той же идее:

public static void DrawRoundedRectangle(Graphics graphics, Rectangle rectangle, Pen pen, int radius)
{
    if (graphics == null)
        throw new ArgumentNullException("graphics");

    SmoothingMode mode = graphics.SmoothingMode;
    graphics.SmoothingMode = SmoothingMode.AntiAlias;

    using (GraphicsPath path = RoundedRectangle(rectangle, radius))
    {
        graphics.DrawPath(pen, path);
    }
    graphics.SmoothingMode = mode;
}
10 голосов
/ 26 июня 2009

Этот метод заполняет скругленный прямоугольник на графическом объекте (код VB):

Public Sub FillRoundedRectangle(ByVal g As Drawing.Graphics, ByVal r As Rectangle, ByVal d As Integer, ByVal b As Brush)
    Dim mode As Drawing2D.SmoothingMode = g.SmoothingMode
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed
    g.FillPie(b, r.X, r.Y, d, d, 180, 90)
    g.FillPie(b, r.X + r.Width - d, r.Y, d, d, 270, 90)
    g.FillPie(b, r.X, r.Y + r.Height - d, d, d, 90, 90)
    g.FillPie(b, r.X + r.Width - d, r.Y + r.Height - d, d, d, 0, 90)
    g.FillRectangle(b, CInt(r.X + d / 2), r.Y, r.Width - d, CInt(d / 2))
    g.FillRectangle(b, r.X, CInt(r.Y + d / 2), r.Width, CInt(r.Height - d))
    g.FillRectangle(b, CInt(r.X + d / 2), CInt(r.Y + r.Height - d / 2), CInt(r.Width - d), CInt(d / 2))
    g.SmoothingMode = mode
End Sub

Чтобы вызвать эту функцию, обработайте событие рисования для поля рисунка и передайте объект e.Graphics в качестве первого аргумента, а границы рисунка - в качестве второго аргумента, если вы хотите, чтобы прямоугольник полностью заполнил ваше поле рисунка.

Параметр d меняет угол наклона, я называю его значением 30, вы можете попробовать разные значения ...

Кроме того, вот код для рисования (вместо заливки) прямоугольника со скругленными углами:

Public Sub DrawRoundedRectangle(ByVal g As Drawing.Graphics, ByVal r As Rectangle, ByVal d As Integer, ByVal p As Pen)
    g.DrawArc(p, r.X, r.Y, d, d, 180, 90)
    g.DrawLine(p, CInt(r.X + d / 2), r.Y, CInt(r.X + r.Width - d / 2), r.Y)
    g.DrawArc(p, r.X + r.Width - d, r.Y, d, d, 270, 90)
    g.DrawLine(p, r.X, CInt(r.Y + d / 2), r.X, CInt(r.Y + r.Height - d / 2))
    g.DrawLine(p, CInt(r.X + r.Width), CInt(r.Y + d / 2), CInt(r.X + r.Width), CInt(r.Y + r.Height - d / 2))
    g.DrawLine(p, CInt(r.X + d / 2), CInt(r.Y + r.Height), CInt(r.X + r.Width - d / 2), CInt(r.Y + r.Height))
    g.DrawArc(p, r.X, r.Y + r.Height - d, d, d, 90, 90)
    g.DrawArc(p, r.X + r.Width - d, r.Y + r.Height - d, d, d, 0, 90)
End Sub
0 голосов
/ 26 июня 2009

Самый простой способ сделать это - создать растровое изображение на лету, используя объект Graphics. Метод DrawEllipse должен быть достаточным.

Затем назначьте это растровое изображение в качестве содержимого объекта PictureBox.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...