Winforms: Smooth the rounded edges for panel

谁说胖子不能爱 提交于 2019-12-04 15:42:30

I was able to solve this by following this link. I just downloaded the sample project and created a new panel. Copied what he had on Form's onpaint to new panel's onpaint and now I have smooth edges.

public class SPanel : Panel
{
    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.FillRoundedRectangle(new SolidBrush(Color.White), 10, 10, this.Width - 40, this.Height - 60, 10);
        SolidBrush brush = new SolidBrush(
            Color.White
            );
        g.FillRoundedRectangle(brush, 12, 12, this.Width - 44, this.Height - 64, 10);
        g.DrawRoundedRectangle(new Pen(ControlPaint.Light(Color.White, 0.00f)), 12, 12, this.Width - 44, this.Height - 64, 10);
        g.FillRoundedRectangle(new SolidBrush(Color.White), 12, 12 + ((this.Height - 64) / 2), this.Width - 44, (this.Height - 64)/2, 10);
    }
}

Here is his GraphicsExtension class if link ever get broken.

static class GraphicsExtension
{
    private static GraphicsPath GenerateRoundedRectangle(
        this Graphics graphics, 
        RectangleF rectangle, 
        float radius)
    {
        float diameter;
        GraphicsPath path = new GraphicsPath();
        if (radius <= 0.0F)
        {
            path.AddRectangle(rectangle);
            path.CloseFigure();
            return path;
        }
        else
        {
            if (radius >= (Math.Min(rectangle.Width, rectangle.Height)) / 2.0)
                return graphics.GenerateCapsule(rectangle);
            diameter = radius * 2.0F;
            SizeF sizeF = new SizeF(diameter, diameter);
            RectangleF arc = new RectangleF(rectangle.Location, sizeF);
            path.AddArc(arc, 180, 90);
            arc.X = rectangle.Right - diameter;
            path.AddArc(arc, 270, 90);
            arc.Y = rectangle.Bottom - diameter;
            path.AddArc(arc, 0, 90);
            arc.X = rectangle.Left;
            path.AddArc(arc, 90, 90);
            path.CloseFigure();
        }
        return path;
    }
    private static GraphicsPath GenerateCapsule(
        this Graphics graphics, 
        RectangleF baseRect)
    {
        float diameter;
        RectangleF arc;
        GraphicsPath path = new GraphicsPath();
        try
        {
            if (baseRect.Width > baseRect.Height)
            {
                diameter = baseRect.Height;
                SizeF sizeF = new SizeF(diameter, diameter);
                arc = new RectangleF(baseRect.Location, sizeF);
                path.AddArc(arc, 90, 180);
                arc.X = baseRect.Right - diameter;
                path.AddArc(arc, 270, 180);
            }
            else if (baseRect.Width < baseRect.Height)
            {
                diameter = baseRect.Width;
                SizeF sizeF = new SizeF(diameter, diameter);
                arc = new RectangleF(baseRect.Location, sizeF);
                path.AddArc(arc, 180, 180);
                arc.Y = baseRect.Bottom - diameter;
                path.AddArc(arc, 0, 180);
            }
            else path.AddEllipse(baseRect);
        }
        catch { path.AddEllipse(baseRect); }
        finally { path.CloseFigure(); }
        return path;
    }

    /// <summary>
    /// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius 
    /// for the arcs that make the rounded edges.
    /// </summary>
    /// <param name="brush">System.Drawing.Pen that determines the color, width and style of the rectangle.</param>
    /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="width">Width of the rectangle to draw.</param>
    /// <param name="height">Height of the rectangle to draw.</param>
    /// <param name="radius">The radius of the arc used for the rounded edges.</param>

    public static void DrawRoundedRectangle(
        this Graphics graphics, 
        Pen pen, 
        float x, 
        float y, 
        float width, 
        float height, 
        float radius)
    {
        RectangleF rectangle = new RectangleF(x, y, width, height);
        GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius);
        SmoothingMode old = graphics.SmoothingMode;
        graphics.SmoothingMode = SmoothingMode.AntiAlias;
        graphics.DrawPath(pen, path);
        graphics.SmoothingMode = old;
    }

    /// <summary>
    /// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius 
    /// for the arcs that make the rounded edges.
    /// </summary>
    /// <param name="brush">System.Drawing.Pen that determines the color, width and style of the rectangle.</param>
    /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
    /// <param name="width">Width of the rectangle to draw.</param>
    /// <param name="height">Height of the rectangle to draw.</param>
    /// <param name="radius">The radius of the arc used for the rounded edges.</param>

    public static void DrawRoundedRectangle(
        this Graphics graphics, 
        Pen pen, 
        int x, 
        int y, 
        int width, 
        int height, 
        int radius)
    {
        graphics.DrawRoundedRectangle(
            pen, 
            Convert.ToSingle(x), 
            Convert.ToSingle(y), 
            Convert.ToSingle(width), 
            Convert.ToSingle(height), 
            Convert.ToSingle(radius));
    }

    /// <summary>
    /// Fills the interior of a rounded rectangle specified by a pair of coordinates, a width, a height
    /// and the radius for the arcs that make the rounded edges.
    /// </summary>
    /// <param name="brush">System.Drawing.Brush that determines the characteristics of the fill.</param>
    /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to fill.</param>
    /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to fill.</param>
    /// <param name="width">Width of the rectangle to fill.</param>
    /// <param name="height">Height of the rectangle to fill.</param>
    /// <param name="radius">The radius of the arc used for the rounded edges.</param>

    public static void FillRoundedRectangle(
        this Graphics graphics, 
        Brush brush, 
        float x, 
        float y, 
        float width, 
        float height, 
        float radius)
    {
        RectangleF rectangle = new RectangleF(x, y, width, height);
        GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius);
        SmoothingMode old = graphics.SmoothingMode;
        graphics.SmoothingMode = SmoothingMode.AntiAlias;
        graphics.FillPath(brush, path);
        graphics.SmoothingMode = old;
    }

    /// <summary>
    /// Fills the interior of a rounded rectangle specified by a pair of coordinates, a width, a height
    /// and the radius for the arcs that make the rounded edges.
    /// </summary>
    /// <param name="brush">System.Drawing.Brush that determines the characteristics of the fill.</param>
    /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to fill.</param>
    /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to fill.</param>
    /// <param name="width">Width of the rectangle to fill.</param>
    /// <param name="height">Height of the rectangle to fill.</param>
    /// <param name="radius">The radius of the arc used for the rounded edges.</param>

    public static void FillRoundedRectangle(
        this Graphics graphics, 
        Brush brush, 
        int x, 
        int y, 
        int width, 
        int height, 
        int radius)
    {
        graphics.FillRoundedRectangle(
            brush, 
            Convert.ToSingle(x), 
            Convert.ToSingle(y), 
            Convert.ToSingle(width), 
            Convert.ToSingle(height), 
            Convert.ToSingle(radius)); 
    }
}

In your code:

 private void ExtendedDraw(PaintEventArgs e)
{
    e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
    e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
    e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, Color.White, Color.White, 90); //here you need your target rectangle

    GraphicsPath path = new GraphicsPath();

    path.StartFigure();
    path.StartFigure();
    path.AddArc(GetLeftUpper(Edge), 180, 90);
    path.AddLine(Edge, 0, Width - Edge, 0);
    path.AddArc(GetRightUpper(Edge), 270, 90);
    path.AddLine(Width, Edge, Width, Height - Edge);
    path.AddArc(GetRightLower(Edge), 0, 90);
    path.AddLine(Width - Edge, Height, Edge, Height);
    path.AddArc(GetLeftLower(Edge), 90, 90);
    path.AddLine(0, Height - Edge, 0, Edge);
    path.CloseFigure();

    e.Graphics.FillPath(brush, path);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!