Winforms:平滑面板的圆边 [英] Winforms: Smooth the rounded edges for panel

查看:165
本文介绍了Winforms:平滑面板的圆边的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循



我想平滑与防别名会做的伎俩,但我想我错了。问题是我该如何平滑边缘?

解决方案

我可以通过以下此链接。我刚下载了示例项目并创建了一个新面板。复制了他在Form的色相上的内容到新面板的色相,现在我有光滑的边缘。

  public class SPanel:Panel 
{
protected override void OnPaint(PaintEventArgs e)
{
图形g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillRoundedRectangle(新的SolidBrush(Color.White),10,10,this.Width - 40,this.Height - 60,10);
SolidBrush brush = new SolidBrush(
Color.White
);
g.FillRoundedRectangle(画笔,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(新的SolidBrush(Color.White),12,12 +((this.Height - 64)/ 2),this.Width - 44,(this.Height - 64)/ 2,10) ;




$ b

这是他的GraphicsExtension类,如果链接被破坏。

  static class GraphicsExtension 
{
private static GraphicsPath GenerateRoundedRectangle(
this graphics graphics,
RectangleF矩形,
浮动半径)
{
浮动直径;
GraphicsPath path = new GraphicsPath();
if(radius <= 0.0F)
{
path.AddRectangle(rectangle);
path.CloseFigure();
返回路径;
}
else
{
if(radius> =(Math.Min(rectangle.Width,rectangle.Height))/ 2.0)
return graphics.GenerateCapsule (长方形);
直径=半径* 2.0F;
SizeF sizeF = new SizeF(直径,直径);
RectangleF arc = new RectangleF(rectangle.Location,sizeF);
path.AddArc(arc,180,90);
arc.X = rectangle.Right - 直径;
path.AddArc(arc,270,90);
arc.Y = rectangle.Bottom - 直径;
path.AddArc(arc,0,90);
arc.X = rectangle.Left;
path.AddArc(arc,90,90);
path.CloseFigure();
}
返回路径;
}
private static GraphicsPath GenerateCapsule(
this Graphics graphics,
RectangleF baseRect)
{
float float;
RectangleF弧;
GraphicsPath path = new GraphicsPath();
如果(baseRect.Width> baseRect.Height)
{
diameter = baseRect.Height;
SizeF sizeF = new SizeF(直径,直径);
arc = new RectangleF(baseRect.Location,sizeF);
path.AddArc(arc,90,180);
arc.X = baseRect.Right - 直径;
path.AddArc(arc,270,180);
}
else if(baseRect.Width< baseRect.Height)
{
diameter = baseRect.Width;
SizeF sizeF = new SizeF(直径,直径);
arc = new RectangleF(baseRect.Location,sizeF);
path.AddArc(arc,180,180);
arc.Y = baseRect.Bottom - 直径;
path.AddArc(arc,0,180);
}
else path.AddEllipse(baseRect);
}
catch {path.AddEllipse(baseRect); }
finally {path.CloseFigure(); }
返回路径;
}

///< summary>
///绘制由一对坐标,宽度,高度和半径指定的圆角矩形
///用于生成圆角边缘的圆弧。
///< / summary>
///< param name =brush> System.Drawing.Pen,用于确定矩形的颜色,宽度和样式。< / param>
///< param name =x>要绘制的矩形的左上角的x坐标< / param>
///< param name =y>绘制矩形左上角的y坐标< / param>
///< param name =width>绘制矩形的宽度< /参数>
///< param name =height>绘制矩形的高度< / param>
///< param name =radius>用于圆边的弧的半径。< / 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>
///绘制由一对坐标,宽度,高度和半径指定的圆角矩形
///用于生成圆角边缘的圆弧。
///< / summary>
///< param name =brush> System.Drawing.Pen,用于确定矩形的颜色,宽度和样式。< / param>
///< param name =x>要绘制的矩形的左上角的x坐标< / param>
///< param name =y>绘制矩形左上角的y坐标< / param>
///< param name =width>绘制矩形的宽度< /参数>
///< param name =height>绘制矩形的高度< / param>
///< param name =radius>用于圆边的弧的半径。< / 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>
///填充由一对坐标,宽度,高度
///指定的圆角矩形的内部以及圆弧边缘的半径。
///< / summary>
///< param name =brush> System.Drawing.Brush,它决定了填充的特征。< / param>
///< param name =x>要填充矩形左上角的x坐标。< / param>
///< param name =y>要填充的矩形左上角的y坐标。< / param>
///< param name =width>要填充的矩形的宽度。< / param>
///< param name =height>要填充矩形的高度。< / param>
///< param name =radius>用于圆边的弧的半径。< / 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>
///填充由一对坐标,宽度,高度
///指定的圆角矩形的内部以及圆弧边缘的半径。
///< / summary>
///< param name =brush> System.Drawing.Brush,它决定了填充的特征。< / param>
///< param name =x>要填充矩形左上角的x坐标。< / param>
///< param name =y>要填充的矩形左上角的y坐标。< / param>
///< param name =width>要填充的矩形的宽度。< / param>
///< param name =height>要填充矩形的高度。< / param>
///< param name =radius>用于圆边的弧的半径。< / 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));
}
}


I have followed this tutorial in order to create a rounded panel. The code in the tutorial is in vb but I was able to convert it to C# so here is my code:

    public class SPanel : Panel
{
    Pen pen;
    float penWidth = 2.0f;
    int _edge = 20;
    Color _borderColor = Color.White;
    public int Edge
    {
        get
        {
            return _edge;
        }
        set
        {
            _edge = value;
            Invalidate();
        }
    }

    public Color BorderColor
    {
        get
        {
            return _borderColor;
        }
        set
        {
            _borderColor = value;
            pen = new Pen(_borderColor, penWidth);
            Invalidate();
        }
    }

    public SPanel()
    {
        pen = new Pen(_borderColor, penWidth);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        ExtendedDraw(e);
        //DrawBorder(e.Graphics);
    }

    private void ExtendedDraw(PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        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();

        Region = new Region(path);
    }

    Rectangle GetLeftUpper(int e)
    {
        return new Rectangle(0, 0, e, e);
    }
    Rectangle GetRightUpper(int e)
    {
        return new Rectangle(Width - e, 0, e, e);
    }
    Rectangle GetRightLower(int e)
    {
        return new Rectangle(Width - e, Height - e, e, e);
    }
    Rectangle GetLeftLower(int e)
    {
        return new Rectangle(0, Height - e, e, e);
    }

    void DrawSingleBorder(Graphics graphics)
    {
        graphics.DrawArc(pen, new Rectangle(0, 0, Edge, Edge), 180, 90);
        graphics.DrawArc(pen, new Rectangle(Width - Edge -1, -1, Edge, Edge), 270, 90);
        graphics.DrawArc(pen, new Rectangle(Width - Edge - 1, Height - Edge - 1, Edge, Edge), 0, 90);
        graphics.DrawArc(pen, new Rectangle(0, Height - Edge - 1, Edge, Edge), 90, 90);

        graphics.DrawRectangle(pen, 0.0F, 0.0F, Width - 1, Height - 1);
    }

    void DrawBorder(Graphics graphics)
    {
        DrawSingleBorder(graphics);
    }
 }

I did not use the border however the result is the same. Here is a ss:

I thought smoothing with anti alias would do the trick but I guess i was wrong. The question is how can I smooth the edges?

解决方案

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

这篇关于Winforms:平滑面板的圆边的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆