You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何CustomButton类绘制的圆形未在Form1显示,仅显示矩形?

自定义圆形Button控件问题解决

问题描述

继承Button类创建了CustomButton,拖入窗体后仍显示为矩形,代码如下:

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

namespace Draw_Shapes
{
    class CustomButton : Button
    {
        protected override void OnPaint(PaintEventArgs pevent)
        {
            base.OnPaint(pevent);

            Draw(pevent.Graphics);
        }

        private void Draw(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // Calculate the center of the form's client area
            int centerX = ClientSize.Width / 2;
            int centerY = ClientSize.Height / 2;

            // Adjust the size of the ellipse based on your requirements
            int ellipseWidth = 800;
            int ellipseHeight = 800;

            // Calculate the position of the ellipse to center it
            int ellipseX = centerX - ellipseWidth / 2;
            int ellipseY = centerY - ellipseHeight / 2;

            Pen myPen = new Pen(Color.Red, 4);
            g.DrawEllipse(myPen, ellipseX, ellipseY, ellipseWidth, ellipseHeight);
            g.FillEllipse(Brushes.Red, ellipseX, ellipseY, ellipseWidth, ellipseHeight);
        }
    }
}

问题原因

  1. 先调用base.OnPaint(pevent)会优先绘制默认的矩形按钮样式,后续绘制的椭圆会被覆盖或仅显示在矩形之上,控件视觉边界仍为矩形。
  2. 椭圆尺寸固定为800,远大于按钮实际大小,导致椭圆无法完整适配按钮区域。
  3. 未设置控件的Region属性,控件的交互区域和视觉边界仍保持矩形。

修正方案

  1. 移除base.OnPaint(pevent)调用,完全自定义绘制逻辑。
  2. 根据按钮实际尺寸绘制圆形(取宽高中最小值保证正圆)。
  3. 设置控件Region为圆形,确保视觉和交互区域统一为圆形。
  4. 增加按钮状态(按下、悬浮)的样式区分,提升交互体验。

修正后的代码

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Draw_Shapes
{
    class CustomButton : Button
    {
        protected override void OnPaint(PaintEventArgs pevent)
        {
            var g = pevent.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // 取宽高中最小值,确保绘制正圆
            int diameter = Math.Min(ClientSize.Width, ClientSize.Height);
            int x = (ClientSize.Width - diameter) / 2;
            int y = (ClientSize.Height - diameter) / 2;
            var circleRect = new Rectangle(x, y, diameter, diameter);

            // 根据按钮状态设置填充色
            Brush fillBrush;
            if (MouseButtons == MouseButtons.Left && ClientRectangle.Contains(PointToClient(MousePosition)))
            {
                fillBrush = Brushes.DarkRed; // 按下状态
            }
            else if (ClientRectangle.Contains(PointToClient(MousePosition)))
            {
                fillBrush = Brushes.OrangeRed; // 悬浮状态
            }
            else
            {
                fillBrush = Brushes.Red; // 默认状态
            }

            // 绘制圆形背景和边框
            g.FillEllipse(fillBrush, circleRect);
            g.DrawEllipse(new Pen(Color.Black, 2), circleRect);

            // 居中绘制按钮文本
            var textRect = new RectangleF(x, y, diameter, diameter);
            StringFormat sf = new StringFormat
            {
                Alignment = StringAlignment.Center,
                LineAlignment = StringAlignment.Center
            };
            g.DrawString(Text, Font, Brushes.White, textRect, sf);
        }

        protected override void OnSizeChanged(System.EventArgs e)
        {
            base.OnSizeChanged(e);
            // 更新控件Region为圆形,确保交互区域匹配视觉
            int diameter = Math.Min(ClientSize.Width, ClientSize.Height);
            int x = (ClientSize.Width - diameter) / 2;
            int y = (ClientSize.Height - diameter) / 2;
            using (var path = new GraphicsPath())
            {
                path.AddEllipse(x, y, diameter, diameter);
                Region = new Region(path);
            }
        }
    }
}

使用说明

  1. 替换原CustomButton类代码为修正后的版本。
  2. 刷新工具箱后重新拖入CustomButton控件到窗体,或重启设计器。
  3. 建议设置按钮宽高一致,确保显示为正圆;若宽高不同,会自动适配为椭圆。

内容的提问来源于stack exchange,提问作者Shien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:57:28