You need to enable JavaScript to run this app. C# WinForm 如何合并四色自定义Label与圆角Label类
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm 如何合并四色自定义Label与圆角Label类

问题根因与实现思路
  • 原RoundedLabel类本身定义残缺:没有继承System.Windows.Forms.Label,代码中用到的OnPaint重写、DoubleBuffered、ClientRectangle等成员,都需要从Label基类继承才能正常使用,原代码本身无法独立运行。
  • 绘制逻辑没有统一裁剪边界:四色填充是直接向整个控件矩形区域绘制,而原圆角效果仅作用于单独的纯色路径,两者没有共享同一个圆角裁剪范围,导致圆角无法约束四色分段的填充内容。

正确的实现逻辑不需要对每段颜色单独做圆角计算:先基于控件大小生成完整的圆角路径,将其设置为Graphics的全局裁剪区域,之后所有的四色分段填充操作都在这个裁剪范围内执行——所有超出圆角边界的填充内容会被自动裁切,从视觉上实现“四色填充的背景整体带四个圆角”的效果。

完整可运行的合并类实现
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class RoundedFourColorLabel : Label
{
    // 四色相关字段,从原CustomLabel迁移
    private Color m_color1 = Color.LightGreen;
    private Color m_color2 = Color.DarkBlue;
    private Color m_color3 = Color.Gray;
    private Color m_color4 = Color.LightYellow;
    private int m_percentage1 = 30;
    private int m_percentage2 = 20;
    private int m_percentage3 = 50;
    private int m_percentage4 = 0;

    // 圆角相关配置
    private int m_cornerRadius = 15;

    public RoundedFourColorLabel()
    {
        // 开启双缓冲,避免自绘闪烁
        DoubleBuffered = true;
        // 配置透明背景支持,避免基类绘制流程覆盖自定义效果
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        BackColor = Color.Transparent;
    }

    #region 四色填充相关属性(完全保留原CustomLabel的使用逻辑)
    [Browsable(true)]
    [Category("自定义外观")]
    public Color Color1
    {
        get => m_color1;
        set { m_color1 = value; Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public Color Color2
    {
        get => m_color2;
        set { m_color2 = value; Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public Color Color3
    {
        get => m_color3;
        set { m_color3 = value; Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public Color Color4
    {
        get => m_color4;
        set { m_color4 = value; Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public int Percentage1
    {
        get => m_percentage1;
        set { m_percentage1 = Math.Max(0, value); Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public int Percentage2
    {
        get => m_percentage2;
        set { m_percentage2 = Math.Max(0, value); Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public int Percentage3
    {
        get => m_percentage3;
        set { m_percentage3 = Math.Max(0, value); Invalidate(); }
    }

    [Browsable(true)]
    [Category("自定义外观")]
    public int Percentage4
    {
        get => m_percentage4;
        set { m_percentage4 = Math.Max(0, value); Invalidate(); }
    }
    #endregion

    #region 圆角相关属性
    [Browsable(true)]
    [Category("自定义外观")]
    public int CornerRadius
    {
        get => m_cornerRadius;
        set 
        { 
            m_cornerRadius = Math.Max(0, Math.Min(value, Height/2)); 
            Invalidate(); 
        }
    }
    #endregion

    // 生成圆角路径的逻辑,从原RoundedLabel迁移
    private GraphicsPath GetRoundRectanglePath(Rectangle rectangle)
    {
        int cornerRadius = m_cornerRadius;
        int diminisher = 1;
        GraphicsPath path = new GraphicsPath();
        
        if (cornerRadius <= 0)
        {
            path.AddRectangle(rectangle);
            path.CloseAllFigures();
            return path;
        }

        path.AddArc(rectangle.X, rectangle.Y, cornerRadius, cornerRadius, 180, 90);
        path.AddArc(rectangle.Right - cornerRadius - diminisher, rectangle.Y, cornerRadius, cornerRadius, 270, 90);
        path.AddArc(rectangle.Right - cornerRadius - diminisher, rectangle.Bottom - cornerRadius - diminisher, cornerRadius, cornerRadius, 0, 90);
        path.AddArc(rectangle.X, rectangle.Bottom - cornerRadius - diminisher, cornerRadius, cornerRadius, 90, 90);
        path.CloseAllFigures();
        return path;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;

        Rectangle clientRect = this.ClientRectangle;
        using (GraphicsPath roundPath = GetRoundRectanglePath(clientRect))
        {
            // 应用裁剪:之后所有绘制操作都不会超出圆角边界
            g.SetClip(roundPath);

            // 计算每一段的宽度,自动对齐控件右边缘,避免百分比加总不等于100%时出现白边
            int totalWidth = clientRect.Width;
            int seg1Width = (int)(totalWidth * Percentage1 / 100.0);
            int seg2Width = (int)(totalWidth * Percentage2 / 100.0);
            int seg3Width = (int)(totalWidth * Percentage3 / 100.0);
            int seg4Width = totalWidth - seg1Width - seg2Width - seg3Width;

            // 绘制四色分段填充,通过using自动释放绘图资源
            using (Brush brush1 = new SolidBrush(Color1))
            {
                g.FillRectangle(brush1, 0, 0, seg1Width, clientRect.Height);
            }
            using (Brush brush2 = new SolidBrush(Color2))
            {
                g.FillRectangle(brush2, seg1Width, 0, seg2Width, clientRect.Height);
            }
            using (Brush brush3 = new SolidBrush(Color3))
            {
                g.FillRectangle(brush3, seg1Width + seg2Width, 0, seg3Width, clientRect.Height);
            }
            using (Brush brush4 = new SolidBrush(Color4))
            {
                g.FillRectangle(brush4, seg1Width + seg2Width + seg3Width, 0, seg4Width, clientRect.Height);
            }

            // 移除裁剪区域,消除圆角边缘的锯齿偏差
            g.ResetClip();
            using (Pen borderPen = new Pen(ForeColor, 1.0f))
            {
                g.DrawPath(borderPen, roundPath);
            }
        }

        // 最后调用基类逻辑绘制文本,保证文本样式和原生Label完全一致
        base.OnPaint(e);
    }
}
关键实现细节
  • 采用单一基类继承结构:直接从System.Windows.Forms.Label派生,避免分层继承导致的OnPaint调用顺序混乱(原分层写法中,四色填充会在圆角绘制之后执行,直接覆盖之前的圆角效果)。
  • 全局裁剪方案:不需要为每段颜色单独计算圆角路径,仅通过Graphics的裁剪机制约束所有填充内容的边界,最终视觉效果为整体圆角的四色背景。
  • 资源泄漏修复:所有GDI+绘图对象(Brush、GraphicsPath)均通过using块自动释放,避免长期运行时出现资源占用问题。
  • 边界对齐优化:第四段填充宽度根据前面三段的实际占用宽度自动计算,无需用户手动保证四个百分比值累加为100%,不会出现边缘白边。
  • 可配置圆角大小:将圆角半径提取为公开属性,可在设计器中直接调整,无需修改代码重新编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 11:06:07