How to make a button with rounded corners in C# (Winforms )

Asked

Viewed 8,181 times

1

I’m trying to customize the appearance of a button, basically I’m trying to customize the edges, background, font color and round the corners of the button. I was able to do everything except round the corners of the button. I tried to follow a tutorial, but it turned out that instead of creating with rounded corners was creating an ellipse.

public class Button : System.Windows.Forms.Button
    {
    protected override void OnPaint(PaintEventArgs e) {
        Color bc = Color.Black;
        Color bg = Color.Red;
        Color fc = Color.White;
        StringFormat formatter = new StringFormat();

        base.OnPaint(e);
        formatter.LineAlignment = StringAlignment.Center;
        formatter.Alignment = StringAlignment.Center;
        RectangleF rectangle = new RectangleF(0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);

        e.Graphics.FillRectangle(new SolidBrush(bg), e.ClipRectangle);
        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, bc, ButtonBorderStyle.Solid);
        e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(fc), rectangle, formatter);
    }
}

I need help to round the edges.

  • The link you have placed has no tutorial. Have you tried changing the values? As you warp an ellipse it can become a rectangle with rounded corners.

  • @Bacco the ideal would be a code in c#, the ide I’m using and windows 2013 , the project is in Win32 saw a lot in css, but for me it does not matter.

  • @bigown The link I posted has a code snippet, if you copy it and put in the project it generates an ellipse, I’ve changed the values, when I changed the height of the ellipse increased, but otherwise it didn’t change much. I tested several values. 5, 20, 2, 200. But I only got the same ellipse as a result.

  • @Bacco a ide é Visual Studio 2013, informei errado. Qual seria sua suggestion para tag?

  • From what I saw from your example, I have the impression that c# and winforms would be the correct tags, regardless of the IDE used. Win32 doesn’t seem to be what you’re looking for, but as I said, it’s just my impression based on what I read, I may not have understood something. PS: Win32 is the "old" windows api, it doesn’t seem to be what you want.

  • 1

    (of course a lot of what you’re using can call Win32 or Win64 internally, for example, but I think the important thing is Winforms itself, as you left it now).

Show 1 more comment

1 answer

2


On the website of MSDN has an example that is working, the code snippet below was taken from there.

I changed the function name SuArredondaRect for BorderRadius, but it’s working. For this code to work pCanto must be greater than 0.

class Transform
{
    public static GraphicsPath BorderRadius(Rectangle pRect, int pCanto, bool pTopo, bool pBase) {
        GraphicsPath gp = new GraphicsPath();

        if (pTopo) {
            gp.AddArc(pRect.X - 1, pRect.Y - 1, pCanto, pCanto, 180, 90);
            gp.AddArc(pRect.X + pRect.Width - pCanto, pRect.Y - 1, pCanto, pCanto, 270, 90);
        } else {
            // Se não arredondar o topo, adiciona as linhas para poder fechar o retangulo junto com
            // a base arredondada
            gp.AddLine(pRect.X - 1, pRect.Y - 1, pRect.X + pRect.Width, pRect.Y - 1);
        }

        if (pBase) {
            gp.AddArc(pRect.X + pRect.Width - pCanto, pRect.Y + pRect.Height - pCanto, pCanto, pCanto, 0, 90);
            gp.AddArc(pRect.X - 1, pRect.Y + pRect.Height - pCanto, pCanto, pCanto, 90, 90);
        } else {
            // Se não arredondar a base, adiciona as linhas para poder fechar o retangulo junto com
            // o topo arredondado. Adiciona da direita para esquerda pois é na ordem contrária que 
            // foi adicionado os arcos do topo. E pra fechar o retangulo tem que desenhar na ordem :
            //  1 - Canto Superior Esquerdo
            //  2 - Canto Superior Direito
            //  3 - Canto Inferior Direito 
            //  4 - Canto Inferior Esquerdo.
            gp.AddLine(pRect.X + pRect.Width, pRect.Y + pRect.Height, pRect.X - 1, pRect.Y + pRect.Height);
        }

        return gp;
    }
}

To work simply call the method BorderRadius class Transform (the code snippet above). An example call based on the current code would be:

public class Button : System.Windows.Forms.Button
    {
    protected override void OnPaint(PaintEventArgs e) {
        Color bc = Color.Black;
        Color bg = Color.Red;
        Color fc = Color.White;
        StringFormat formatter = new StringFormat();

        base.OnPaint(e);
        formatter.LineAlignment = StringAlignment.Center;
        formatter.Alignment = StringAlignment.Center;
        RectangleF rectangle = new RectangleF(0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);

        e.Graphics.FillRectangle(new SolidBrush(bg), e.ClipRectangle);
        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle, bc, ButtonBorderStyle.Solid);
        e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(fc), rectangle, formatter);

        // BorderRadius é uma variável do tipo inteiro que define a quantidade que a borda deve ser arredondada.
        if (BorderRadius > 0) {
            GraphicsPath gp = Transform.BorderRadius(ClientRectangle, BorderRadius, true, true);
            this.Region = new System.Drawing.Region(gp);
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.