圆形按钮

9

如何制作一个圆形按钮而不是传统的矩形按钮。

我正在使用winforms(2.0)。


你是在说ASP.NET还是WinForms?如果是后者,我不知道。如果是前者,这是一个CSS问题,请谷歌搜索“CSS圆角”。 - RPM1984
7个回答

35

首先创建一个类,将其命名为“RoundButton”。 然后直接编写以下代码:

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

}

然后,构建应用程序并关闭它。

现在进入工具箱,你会看到一个名为RoundButton的控件。

然后将其拖放到Windows表单上进行测试。


2
我使用了这段代码,但我的按钮左侧和底部有裁剪,有人可以帮忙解决吗? - Ayush Bhargava
@AyushBhargava:这是因为设置Region属性只需要普通的按钮(包括其不同颜色的边界),并切掉超出给定路径的所有内容,留下旧边界的一些残留物。您将不得不自己重新绘制形状的边界(即除了设置Region之外,您还必须绘制一个比Region小一点的空心椭圆)。请参见:https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.region?view=netframework-4.7.2 - oliver
3
简单的解决方法是将RoundButton的FlatStyle属性设置为Flat,将BorderSize属性设置为0,在FlatAppearance属性下。这样就不会再出现剪切问题了。 - Peck_conyon

10
GraphicsPath p = new GraphicsPath();
p.AddEllipse(1, 1, button1.Width - 4, button1.Height - 4);
button1.Region = new Region(p);

这是我想到的最好的解决方案。为什么这个解决方案没有得到更多的赞? - Somanna

6

2

这个或者这个可以帮助你实现自己的按钮类,基于默认的Windows Forms按钮。你也可以在网上搜索更多的例子。


1

请问 'GDI' 是什么?

实现示例:

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

扩展以限制圆角半径 (*范围:0-90)

作者: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

这就是你想要的

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

优点:

  • 没有切割

  • 圆形

缺点:

  • 圆形按钮的设计加载器错误

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

你可以这样调用:

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

Controls.AddRange(new Control[] 
{
    menu
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接