9

How do I make a button in a round shape rather than the conventional rectangle.

I am using winforms(2.0)

Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
karthik
  • 4,485
  • 8
  • 30
  • 45
  • are you talking ASP.NET, or are you talking WinForms. If the latter, i have no idea. If the former, this is a CSS question, google "CSS Rounded Corners" – RPM1984 Sep 14 '10 at 10:45

7 Answers7

35

First make a class. Give it name: "RoundButton". Then write the code directly as this:

using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
    public class RoundButton : Button
    {
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            GraphicsPath grPath = new GraphicsPath();
            grPath.AddEllipse(0, 0, ClientSize.Width, ClientSize.Height);
            this.Region = new System.Drawing.Region(grPath);
            base.OnPaint(e);
        }
    }

}

Then, build your application and close this.

Now go to the toolbox and you will see a control named RoundButton.

Then drag and drop this on your Windows form and test it.

Emma
  • 27,428
  • 11
  • 44
  • 69
Salman Srabon
  • 351
  • 3
  • 2
  • 2
    I used this code, but my button has cuts on the left and bottom side, can anyone help with that? – Ayush Bhargava Sep 23 '18 at 09:00
  • @AyushBhargava: the reason for this is that setting the Region property just takes the ordinary button (including its differently colored boundary) and cuts everything off that's outside the given path, leaving some remnants of the old boundary. You will have to redraw the boundary of the shape yourself (i.e. besides setting Region, you'll have to draw a hollow ellipse, that is a little smaller than the Region). See: https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.region?view=netframework-4.7.2 – oliver Dec 10 '18 at 07:30
  • 3
    A simple solution will be to set the RoundButton's FlatStyle property to Flat and BorderSize to 0 under FlatAppearance property. Then there are no more cuts – Peck_conyon Sep 28 '19 at 13:11
10
GraphicsPath p = new GraphicsPath();
p.AddEllipse(1, 1, button1.Width - 4, button1.Height - 4);
button1.Region = new Region(p);
Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
Jig12
  • 2,977
  • 4
  • 23
  • 28
6

Code project has many articles about these kinds of things, especially the article RoundButton Windows Control - Ever Decreasing Circles might be of interest since it shows you have to do different kinds of round buttons.

Hans Olsson
  • 54,199
  • 15
  • 94
  • 116
2

This or this could help if you need to implement your own Button class based on the default Windows Forms button. You can also search online for more examples.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Adrian Fâciu
  • 12,414
  • 3
  • 53
  • 68
1

What about 'GDI'?

Implementation Example:

 #region <Round Corners> : (Properties)
        // [Use Round Corners]
        private bool useRoundCorners = false;

        [Category("Control Corners"), DisplayName("Round Corners")]
        [Description("Set Round Corners.")]
        [Browsable(true)]
        public bool UseRoundBorders
        {
            get { return useRoundCorners; }
            set { if (useRoundCorners != value) { useRoundCorners = value; Invalidate(); } }
        }

        // [Ellipse Radius]
        private int ellipseRadius = 20;

        [Category("Control Corners"), DisplayName("Radius")]
        [Description("Set Corner (Ellipse) Radius")]
        [Browsable(true)]
        public int EllipseRadius
        {
            get { return ellipseRadius.FixedValue(0, 90); }
            set { if (ellipseRadius != value.FixedValue(0, 90)) { ellipseRadius = value; Invalidate(); } }
        }
        #endregion

        #region <Round Corners> : (Draw)
        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        private static extern IntPtr CreateRoundRectRgn
        (
            int nLeftRect,     // x-coordinate of upper-left corner
            int nTopRect,      // y-coordinate of upper-left corner
            int nRightRect,    // x-coordinate of lower-right corner-
            int nBottomRect,   // y-coordinate of lower-right corner
            int nWidthEllipse, // width of ellipse
            int nHeightEllipse // height of ellipse
        );


        /// <summary> Draw Corners (Round or Square). </summary>
        /// <param name="e"></param>
        private void DrawCorners()
        {
            if (useRoundCorners) { this.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, ellipseRadius, ellipseRadius)); }
            else { this.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 0, 0)); }
        }
        #endregion

    /// <summary> Redraw (Update) the Control. </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        DrawCorners();
    }    

Extension to Limit Round Corner Radius (*Range: 0-90)

Author: Salvador

// Extension to Set Min. & Max. Values to Properties
public static class Extensions
{
    public static int FixedValue(this int value, int min, int max)
    {
        if (value >= min && value <= max) { return value; }
        else if (value > max) { return max; }
        else if (value < min) { return min; }
        else { return 1; }
    }
}

0

This is what you want

public class RoundButton : Control
{
    private readonly Label lbl;
    public RoundButton() : base()
    {
        lbl = new Label
        {
            Text = Text,
            ForeColor = ForeColor,
            BackColor = BackColor,
            Font = Font
        };
        CenterInParent();
    }
    private void CenterInParent()
    {
        lbl.Left = (Width - lbl.Width) / 2;
        lbl.Top = (Height - lbl.Height) / 2;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        GraphicsPath grPath = new GraphicsPath();
        grPath.AddEllipse(0, 0, ClientSize.Width, ClientSize.Height);
        Region = new Region(grPath);
        base.OnPaint(e);
    }
    protected override void OnMove(EventArgs e)
    {
        CenterInParent();
        base.OnMove(e);
    }
    protected override void OnTextChanged(EventArgs e)
    {
        lbl.Text = Text;
        base.OnTextChanged(e);
    }
    protected override void OnForeColorChanged(EventArgs e)
    {
        lbl.ForeColor = ForeColor;
        base.OnForeColorChanged(e);
    }
    protected override void OnBackColorChanged(EventArgs e)
    {
        lbl.BackColor = BackColor;
        base.OnBackColorChanged(e);
    }
    protected override void OnFontChanged(EventArgs e)
    {
        lbl.Font = Font;
        base.OnFontChanged(e);
    }
}

Pros:

  • No cuts

  • Round

Cons:

  • Wrong designer loader for round button
0
public class OptionsMenu : Button
{
    public OptionsMenu(int NoOfOptions, Point Location, ControlCollection controls,
                       Size ButtonSize, int DistanceBetweenOptions)
    {
        Button[] buttons = new Button[NoOfOptions];

        for (int i = 0; i < NoOfOptions; i++)
        {
            buttons[i] = new Button()
            {
                Size = ButtonSize,
            };

            GraphicsPath p = new GraphicsPath();
            p.AddEllipse(1, 1, buttons[i].Width - 4, buttons[i].Height - 4);
            buttons[i].Region = new Region(p);
            buttons[i].Location = new Point(Location.X, Location.Y + DistanceBetweenOptions * i);

            controls.Add(buttons[i]);
        }
    }
}

You can call it like this:

OptionsMenu menu = new OptionsMenu(4, new Point(50, 50), Controls, new Size(20, 20), 40);

Controls.AddRange(new Control[] 
{
    menu
});
Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35