为何CustomButton类绘制的圆形未在Form1显示,仅显示矩形?
问题描述
继承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); } } }
问题原因
- 先调用
base.OnPaint(pevent)会优先绘制默认的矩形按钮样式,后续绘制的椭圆会被覆盖或仅显示在矩形之上,控件视觉边界仍为矩形。 - 椭圆尺寸固定为800,远大于按钮实际大小,导致椭圆无法完整适配按钮区域。
- 未设置控件的
Region属性,控件的交互区域和视觉边界仍保持矩形。
修正方案
- 移除
base.OnPaint(pevent)调用,完全自定义绘制逻辑。 - 根据按钮实际尺寸绘制圆形(取宽高中最小值保证正圆)。
- 设置控件
Region为圆形,确保视觉和交互区域统一为圆形。 - 增加按钮状态(按下、悬浮)的样式区分,提升交互体验。
修正后的代码
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); } } } }
使用说明
- 替换原CustomButton类代码为修正后的版本。
- 刷新工具箱后重新拖入CustomButton控件到窗体,或重启设计器。
- 建议设置按钮宽高一致,确保显示为正圆;若宽高不同,会自动适配为椭圆。
内容的提问来源于stack exchange,提问作者Shien
相关产品推荐
相关产品推荐

