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

如何为重写OnPaint的ToolStripStatusLabel子类添加缺失属性支持?

完善SpringLabel类以支持ToolStripStatusLabel原有属性

问题背景

我实现了一个继承自ToolStripStatusLabel的SpringLabel类,开启Spring属性并重写OnPaint方法实现了超长文本的省略显示,但该类缺失父控件的BorderSides、图片等属性支持。现有@Hans提供的解决方案代码可正常运行,但仍不支持图片属性,且要求父StatusStrip控件的LayoutStyle设为默认的Table。

现有代码的问题

现有方案重新定义了Text属性,导致与父类的属性逻辑脱节;同时在OnPaint中先调用base.OnPaint再叠加绘制文本,会导致原文本和新绘制的省略文本重叠,且父类的图片、边框绘制逻辑被干扰或未正确复用。

完善后的实现方案

要复用ToolStripStatusLabel的原有行为,核心是不破坏父类的属性体系,仅在文本绘制环节做省略处理,同时保留父类对图片、边框等属性的绘制逻辑:

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.StatusStrip)]
public class SpringLabel : ToolStripStatusLabel
{
    public SpringLabel()
    {
        Spring = true;
        // 绑定ToolTip到父类Text属性,无需自定义字段
        ToolTipText = Text;
    }

    // 重写Text属性的setter,同步更新ToolTip和触发重绘
    public override string Text
    {
        get => base.Text;
        set
        {
            base.Text = value;
            ToolTipText = value;
            Invalidate();
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // 先让父类完成边框、图片等元素的绘制
        base.OnPaint(e);

        // 计算文本绘制的有效区域:排除图片和内边距
        var contentRect = GetTextBounds();
        if (contentRect.Width <= 0 || string.IsNullOrEmpty(Text))
            return;

        // 使用TextRenderer绘制带省略号的文本,对齐方式与父类保持一致
        var textFormatFlags = GetTextFormatFlags();
        TextRenderer.DrawText(e.Graphics, Text, Font, contentRect, ForeColor, textFormatFlags);
    }

    // 获取文本实际绘制区域,考虑图片、内边距和边框
    private Rectangle GetTextBounds()
    {
        var bounds = ClientRectangle;

        // 调整区域以排除图片占用的空间
        if (Image != null)
        {
            bounds.X += Image.Width + ImageMargin.Horizontal;
            bounds.Width -= Image.Width + ImageMargin.Horizontal;
        }

        // 减去内边距
        bounds.X += Padding.Left;
        bounds.Width -= Padding.Left + Padding.Right;

        // 减去边框占用的空间
        if (BorderSides != ToolStripStatusLabelBorderSides.None)
        {
            var borderWidth = SystemInformation.Border3DSize.Width;
            bounds.X += borderWidth;
            bounds.Width -= borderWidth * 2;
        }

        return bounds;
    }

    // 获取与父类一致的文本格式标记,包含省略号设置
    private TextFormatFlags GetTextFormatFlags()
    {
        var flags = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter;

        // 对齐方式与父类TextAlign保持一致
        switch (TextAlign)
        {
            case ContentAlignment.TopLeft:
                flags |= TextFormatFlags.Top | TextFormatFlags.Left;
                break;
            case ContentAlignment.TopCenter:
                flags |= TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
                break;
            case ContentAlignment.TopRight:
                flags |= TextFormatFlags.Top | TextFormatFlags.Right;
                break;
            case ContentAlignment.MiddleLeft:
                flags |= TextFormatFlags.Left;
                break;
            case ContentAlignment.MiddleCenter:
                flags |= TextFormatFlags.HorizontalCenter;
                break;
            case ContentAlignment.MiddleRight:
                flags |= TextFormatFlags.Right;
                break;
            case ContentAlignment.BottomLeft:
                flags |= TextFormatFlags.Bottom | TextFormatFlags.Left;
                break;
            case ContentAlignment.BottomCenter:
                flags |= TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
                break;
            case ContentAlignment.BottomRight:
                flags |= TextFormatFlags.Bottom | TextFormatFlags.Right;
                break;
        }

        return flags;
    }
}

关键改进点

  • 复用父类属性体系:不再自定义_sltext字段,直接重写Text属性的setter,同步更新ToolTipText,保证与父类属性逻辑一致。
  • 保留原有绘制逻辑:先调用base.OnPaint完成边框、图片等元素的绘制,仅在父类绘制基础上覆盖处理后的文本。
  • 适配图片与边框:通过GetTextBounds方法计算排除图片、内边距和边框后的文本区域,确保文本绘制位置正确。
  • 对齐方式兼容:通过GetTextFormatFlags方法匹配父类的TextAlign设置,保持原有对齐行为。

注意事项

  • Spring属性本身依赖StatusStrip的LayoutStyle为Table,这是ToolStrip控件的原生布局逻辑,无法完全规避。
  • 若需要支持更多父类属性(如BorderStyle),可在GetTextBounds或OnPaint中进一步适配父类的属性值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:05:16