2009-06-26 3 views
5

Я хотел бы создать заполненный округленный прямоугольник во время выполнения и назначить его как содержимое PictureBox (уже созданного и скрытого) в Windows Forms.Как создать округленный прямоугольник во время выполнения в Windows Forms с помощью VB.NET/C#?

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

ответ

8

Этот метод заполняет прямоугольник с закругленными углами на графический объект (код 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 

вызывать эту функцию, обрабатывающий событие краской PictureBox и передать 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

эй Мета -Наношь, спасибо большое за твою молнию! : D Код работает очень хорошо. Еще один вопрос, как я могу это сделать, если я не хочу рисовать его немедленно, но только тогда, когда приложение находится в определенном состоянии? Должен ли я использовать в этом случае событие Paint? – Drake

+0

Вы можете иметь логическое значение в своем классе (предположим, это называется mustPaint), которое вы задаете, когда хотите, чтобы прямоугольник был нарисован, тогда вы могли бы добавить условие в событие Paint: , если mustPaint затем [нарисовать закругленный прямоугольник здесь] end if –

+0

ok, я попробую, спасибо – Drake

0

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

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

13

Проблема с решением заливки, отмеченным как ответ, плохо работает с не сплошными/равномерными кистями. Вот еще один основанный на классе 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; 
} 

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

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; 
} 
Смежные вопросы