如何使用 VB.NET/C# 在 Windows 窗体中运行时创建圆角矩形?

发布于 2024-07-25 08:35:56 字数 88 浏览 4 评论 0原文

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

您知道我该如何实施吗?

I woud like to create a filled rounded rectangle at run-time and assign it as content of a PictureBox (already created and hidden) in Windows Forms.

Do you have an idea how can I implement it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微暖i 2024-08-01 08:35:56

标记为答案的填充解决方案的问题是它不适用于非固体/均匀画笔。 这是另一个基于 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;
}

The problem with the fill solution that is marked as the answer is it does not work well with non solid/uniform brushes. Here is another one based on the GraphicsPath class wich I think is more reusable:

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;
}

and here is the code for Draw only (not fill), based on the same idea:

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;
}
2024-08-01 08:35:56

此方法填充图形对象上的圆角矩形(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

This method fills a rounded rectangle on a graphics object (VB code) :

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

To call this function, handle the paint event of the picturebox and pass the e.Graphics object as the first argument, and the picturebox's bounds as the second argument if you want the rectangle to fill your picture box completely.

The d parameter changes the corners' angle, I call it with a value of 30, you can try different values...

Also, here's some code to draw (instead of fill) a rounded rectangle:

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
各空 2024-08-01 08:35:56

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

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

The easiest way to do this is to create a Bitmap on the fly using the Graphics object. The DrawEllipse method should suffice.

Then assign that Bitmap as the contents of the PictureBox object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文