Label with smooth rounded corners

10,492

Solved it according to this answer by @Reza Aghaei.

Solution

using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class RoundLabel : Label
{
    [Browsable(true)]
    public Color _BackColor { get; set; }

    public RoundLabel()
    {
        this.DoubleBuffered = true;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        using (var graphicsPath = _getRoundRectangle(this.ClientRectangle))
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            using (var brush = new SolidBrush(_BackColor))
                e.Graphics.FillPath(brush, graphicsPath);
            using (var pen = new Pen(_BackColor, 1.0f))
                e.Graphics.DrawPath(pen, graphicsPath);
            TextRenderer.DrawText(e.Graphics, Text, this.Font, this.ClientRectangle, this.ForeColor);
        }
    }

    private GraphicsPath _getRoundRectangle(Rectangle rectangle)
    {
        int cornerRadius = 15; // change this value according to your needs
        int diminisher = 1;
        GraphicsPath path = new GraphicsPath();
        path.AddArc(rectangle.X, rectangle.Y, cornerRadius, cornerRadius, 180, 90);
        path.AddArc(rectangle.X + rectangle.Width - cornerRadius - diminisher, rectangle.Y, cornerRadius, cornerRadius, 270, 90);
        path.AddArc(rectangle.X + rectangle.Width - cornerRadius - diminisher, rectangle.Y + rectangle.Height - cornerRadius - diminisher, cornerRadius, cornerRadius, 0, 90);
        path.AddArc(rectangle.X, rectangle.Y + rectangle.Height - cornerRadius - diminisher, cornerRadius, cornerRadius, 90, 90);
        path.CloseAllFigures();
        return path;
    }
}
Share:
10,492
Pollitzer
Author by

Pollitzer

I'm a body fisher in the Mediterranean. Native language: German Gender: male

Updated on June 27, 2022

Comments

  • Pollitzer
    Pollitzer almost 2 years

    2 labels in windows form

    Both labels have AutoSize true & TextAlign MiddleCenter.

    How can also label2 show smooth borders?

    Here is the test code for handlers Form.Load(...) & Form.Paint(...):

    int _cornerRadius = 10;
    Point _locationLabel2;
    
    // Form.Load(...)
    private void Form3_Load(object sender, EventArgs e)
    {
        // Step 1: Cut the label regions (seems to be ok, result is the same for both labels)
        GraphicsPath graphicsPath = _getRoundPath(label1.ClientRectangle, _cornerRadius);
        label1.Region = new Region(graphicsPath);
        graphicsPath = _getRoundPath(label2.ClientRectangle, _cornerRadius);
        label2.Region = new Region(graphicsPath);
    
        _locationLabel2 = this.PointToClient(label2.Parent.PointToScreen(label2.Location));
    }
    
    // Form.Paint(...)
    private void Form3_Paint(object sender, PaintEventArgs e)
    {
        using (Pen pen = new Pen(label1.BackColor, 3.0f))
        {
            // Step 2: Smooth the label borders (ok only for label1)
            _drawRoundedRectangle(e.Graphics, pen, label1.Location.X, label1.Location.Y, 
                                  label1.ClientRectangle.Width, label1.ClientRectangle.Height, _cornerRadius);
            _drawRoundedRectangle(e.Graphics, pen, _locationLabel2.X, _locationLabel2.Y,
                                  label2.ClientRectangle.Width, label2.ClientRectangle.Height, _cornerRadius);
        }
    }
    
    // Helper 1/3
    private static GraphicsPath _getRoundPath(Rectangle rectangle, int radius)
    {
        int x = rectangle.X;
        int y = rectangle.Y;
        int width = rectangle.Width;
        int height = rectangle.Height;
    
        radius = radius << 1;
    
        GraphicsPath path = new GraphicsPath();
    
        if (radius > 0)
        {
            if (radius > height) radius = height;
            if (radius > width) radius = width;
            path.AddArc(x, y, radius, radius, 180, 90);
            path.AddArc(x + width - radius, y, radius, radius, 270, 90);
            path.AddArc(x + width - radius, y + height - radius, radius, radius, 0, 90);
            path.AddArc(x, y + height - radius, radius, radius, 90, 90);
            path.CloseFigure();
        }
        else
        {
            path.AddRectangle(rectangle);
        }
    
        return path;
    }
    
    // Helper 2/3
    private void _drawRoundedRectangle(Graphics graphics, Pen pen, int x, int y, int width, int height, int radius)
    {
        RectangleF rectangle = new RectangleF(x, y, width, height);
        GraphicsPath path = _generateRoundedRectangle(graphics, rectangle, radius);
        SmoothingMode old = graphics.SmoothingMode;
        graphics.SmoothingMode = SmoothingMode.AntiAlias;
        graphics.DrawPath(pen, path);
        graphics.SmoothingMode = old;
    }
    
    // Helper 3/3
    private static GraphicsPath _generateRoundedRectangle(Graphics graphics, RectangleF rectangle, int radius)
    {
        GraphicsPath path = new GraphicsPath();
        float 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;
    }
    

    Main code parts are from Arun Reginald Zaheeruddin