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

WinForms窗体圆角失效及Panel控件无法实现圆角的解决方案需求

WinForms圆角窗体与控件问题解决方案

问题描述

开发Windows Forms应用时,已实现窗体圆角效果,但存在两个问题:

  • Panel等控件无法应用圆角效果
  • 添加Panel后,窗体的圆角效果失效

需求:

  1. 添加控件后仍保留窗体的圆角效果
  2. Panel等控件可实现平滑过渡的圆角效果

原实现代码

#region Rounded Corner

protected override void OnLoad(EventArgs e)
{
    if (!DesignMode)
    {
        drawTimer.Interval = 1000 / 60;
        drawTimer.Tick += DrawForm;
        drawTimer.Start();
    }

    base.OnLoad(e);
}

private void DrawForm(object sender, EventArgs e)
{
   using (Bitmap backImage = new Bitmap(this.Width, this.Height))
   {
      using (Graphics graphics = Graphics.FromImage(backImage))
      {
         Rectangle gradientRectangle = new Rectangle(0, 0, 
                                this.Width - 1, this.Height - 1);
          using (Brush b = new LinearGradientBrush(gradientRectangle, 
          Color.FromArgb(70, 95, 122), Color.FromArgb(70, 95, 122), 0.0f))
          {
              graphics.SmoothingMode = SmoothingMode.HighQuality;

              RoundedRectangle.FillRoundedRectangle(graphics, b, gradientRectangle, 20);

              foreach (Control ctrl in this.Controls)
              {
                  using (Bitmap bmp = new Bitmap(ctrl.Width, ctrl.Height))
                  {
                      Rectangle rect = new Rectangle(0, 0, ctrl.Width, ctrl.Height);
                      ctrl.DrawToBitmap(bmp, rect);
                      graphics.DrawImage(bmp, ctrl.Location);
                  }
              }

              PerPixelAlphaBlend.SetBitmap(backImage, Left, Top, Handle);
         }
    }
}

protected override void OnPaint(PaintEventArgs e)
{
    if (DesignMode)
    {
        Graphics graphics = e.Graphics;

        Rectangle gradientRectangle = new Rectangle(0, 0, this.Width - 1, this.Height - 1);

        using (Brush brush = new LinearGradientBrush(gradientRectangle, Color.FromArgb(70, 95, 122), Color.FromArgb(70, 95, 122), 0.0f))
        {
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            RoundedRectangle.FillRoundedRectangle(graphics, brush, gradientRectangle, 40);
        }
    }

    base.OnPaint(e);
}

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;

        if (!DesignMode)
        {
            cp.ExStyle |= 0x00080000;
        }
        return cp;
    }
}
#endregion

解决方案

一、修复窗体圆角失效问题

原方案通过定时器绘制控件到Bitmap再叠加的方式会覆盖圆角区域,且分层窗体(WS_EX_LAYERED)的控件绘制逻辑容易冲突,调整如下:

  1. 基础设置调整

    • 将窗体FormBorderStyle设为None(如需自定义标题栏),或保留默认但确保BackColor与圆角背景色一致
    • 移除drawTimer相关逻辑,改用OnPaintBackground绘制圆角背景,避免控件覆盖
  2. 重写窗体绘制方法

public partial class RoundedForm : Form
{
    private int _cornerRadius = 20;
    private Color _formColor = Color.FromArgb(70, 95, 122);

    public RoundedForm()
    {
        InitializeComponent();
        // 开启双缓冲避免闪烁
        DoubleBuffered = true;
        SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // 不调用基类方法,避免绘制默认矩形背景
        using (var brush = new SolidBrush(_formColor))
        {
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            // 绘制圆角背景
            RoundedRectangle.FillRoundedRectangle(e.Graphics, brush, ClientRectangle, _cornerRadius);
        }
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            if (!DesignMode)
            {
                cp.ExStyle |= 0x00080000; // WS_EX_LAYERED
                cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT,确保控件区域不遮挡圆角
            }
            return cp;
        }
    }
}

二、实现带圆角的自定义Panel

创建自定义控件继承自Panel,重写绘制逻辑实现平滑圆角:

public class RoundedPanel : Panel
{
    private int _cornerRadius = 15;
    private Color _panelColor = Color.White;

    public int CornerRadius
    {
        get => _cornerRadius;
        set
        {
            _cornerRadius = value;
            Invalidate();
        }
    }

    public Color PanelColor
    {
        get => _panelColor;
        set
        {
            _panelColor = value;
            Invalidate();
        }
    }

    public RoundedPanel()
    {
        DoubleBuffered = true;
        SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
        BackColor = Color.Transparent; // 设为透明,避免矩形背景透出
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
        using (var brush = new SolidBrush(_panelColor))
        {
            RoundedRectangle.FillRoundedRectangle(e.Graphics, brush, ClientRectangle, _cornerRadius);
        }
        // 绘制子控件
        base.OnPaint(e);
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // 不绘制默认背景,避免遮挡圆角
    }
}

三、关键注意事项

  • 确保RoundedRectangle工具类的FillRoundedRectangle方法使用抗锯齿绘制,保证圆角平滑
  • 所有需要圆角的控件(如Panel)都使用自定义的RoundedPanel,而非原生Panel
  • 分层窗体(WS_EX_LAYERED)下避免使用DrawToBitmap绘制控件,直接让控件自行绘制即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:29:54