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

为何自定义CircularPanel圆形面板控件显示模糊且边角扁平?

问题修复方案

问题原因

  • 直接在OnPaint方法中修改Region会触发反复重绘,同时WinForm原生Region本身不支持抗锯齿,硬裁剪的边缘会呈现锯齿模糊效果
  • 没有监听控件大小变化事件,控件拉伸后Region没有同步更新,宽高不等时椭圆自然会被压扁
  • 未开启控件双缓冲和高DPI适配,也会加剧显示模糊问题

修复代码

class CircularPanel : Panel
{
    public CircularPanel()
    {
        // 开启双缓冲、用户自绘,减少闪烁
        DoubleBuffered = true;
        SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
        // 背景设为透明,避免硬裁剪边缘
        BackColor = Color.Transparent;
        // 大小变化时自动重绘
        SizeChanged += (s, e) => Invalidate();
        // 可选:强制控件保持正方形,避免椭圆被压扁
        //SizeChanged += (s, e) => { if (Width != Height) Height = Width; };
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // 开启抗锯齿,让边缘平滑
        e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        e.Graphics.Clear(Parent.BackColor);
        
        // 绘制圆形背景和边框
        using (GraphicsPath g = new GraphicsPath())
        {
            // 这里缩进1像素,避免边缘被控件裁剪
            g.AddEllipse(1, 1, ClientSize.Width - 2, ClientSize.Height - 2);
            // 填充面板背景色
            using (Brush brush = new SolidBrush(BackColor))
            {
                e.Graphics.FillPath(brush, g);
            }
            // 可选:绘制边框
            // using (Pen pen = new Pen(Color.Black, 1))
            // {
            //     e.Graphics.DrawPath(pen, g);
            // }
        }

        base.OnPaint(e);
    }
}

额外配置

如果你的项目运行在高DPI系统下,需要在Program.cs的Application.Run之前添加高DPI适配代码:

Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);

如果需要严格的圆形效果,可以取消代码中强制宽高相等的注释,控件会自动保持正方形不会被拉伸压扁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:15:04