代码之家  ›  专栏  ›  技术社区  ›  Drake

如何在运行时使用vb.net/c在Windows窗体中创建圆角矩形?

  •  6
  • Drake  · 技术社区  · 15 年前

    我希望在运行时创建一个填充的圆角矩形,并将其指定为Windows窗体中PictureBox(已创建和隐藏)的内容。

    你知道我如何实现它吗?

    3 回复  |  直到 15 年前
        1
  •  9
  •   Meta-Knight    15 年前

    此方法填充图形对象上的圆角矩形(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对象作为第一个参数传递,如果希望矩形完全填充图片框,则将PictureBox的边界作为第二个参数传递。

    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
    
        2
  •  13
  •   Simon Mourier    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;
    }
    
        3
  •  0
  •   JaredPar    15 年前

    最简单的方法是使用图形对象动态创建位图。DrawEllipse方法应该足够了。

    然后将该位图指定为PictureBox对象的内容。