Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.
This repository was archived by the owner on May 15, 2026. It is now read-only.

Here's a .NET9 version #3

Description

@pmeems

Thanks for your great work. It was just what I was looking for.

With a little help from ChatGPT I made a .NET9 version which still works very nicely.
I thought I share it here for others to use:

using System.ComponentModel;

#pragma warning disable WFO1000

namespace WinFormApplication;

public class TextProgressBar : ProgressBar
{
    private Font _textFont = new(FontFamily.GenericSerif, 11, FontStyle.Bold | FontStyle.Italic);
    private SolidBrush _textBrush = new(Color.Black);
    private SolidBrush _progressBrush = new(Color.LightGreen);
    private ProgressBarDisplayMode _visualMode = ProgressBarDisplayMode.CurrProgress;
    private string _customText = string.Empty;

    [Category("Appearance")]
    [Description("Font of the text displayed on the progress bar.")]
    public Font TextFont
    {
        get => _textFont;
        set
        {
            _textFont = value ?? throw new ArgumentNullException(nameof(TextFont));
            Invalidate();
        }
    }

    [Category("Appearance")]
    [Description("Color of the text displayed on the progress bar.")]
    public Color TextColor
    {
        get => _textBrush.Color;
        set
        {
            if (_textBrush.Color != value)
            {
                _textBrush.Dispose();
                _textBrush = new SolidBrush(value);
                Invalidate();
            }
        }
    }

    [Category("Appearance")]
    [Description("Color of the progress bar.")]
    public Color ProgressColor
    {
        get => _progressBrush.Color;
        set
        {
            if (_progressBrush.Color != value)
            {
                _progressBrush.Dispose();
                _progressBrush = new SolidBrush(value);
                Invalidate();
            }
        }
    }

    [Category("Behavior")]
    [Description("Defines the text display mode of the progress bar.")]
    public ProgressBarDisplayMode VisualMode
    {
        get => _visualMode;
        set
        {
            if (_visualMode != value)
            {
                _visualMode = value;
                Invalidate();
            }
        }
    }

    [Category("Behavior")]
    [Description("Custom text to display on the progress bar.")]
    public string CustomText
    {
        get => _customText;
        set
        {
            _customText = value;
            Invalidate();
        }
    }

    public TextProgressBar()
    {
        SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint,
            value: true);
    }

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

        DrawProgressBar(g);
        DrawText(g);
    }

    private void DrawProgressBar(Graphics g)
    {
        var rect = ClientRectangle;

        ProgressBarRenderer.DrawHorizontalBar(g, rect);
        rect.Inflate(-3, -3);

        if (Value > 0)
        {
            var fillWidth = (int)((Value - Minimum) / (float)(Maximum - Minimum) * rect.Width);
            var fillRect = new Rectangle(rect.X, rect.Y, fillWidth, rect.Height);
            g.FillRectangle(_progressBrush, fillRect);
        }
    }

    private void DrawText(Graphics g)
    {
        if (VisualMode == ProgressBarDisplayMode.NoText)
            return;

        var text = GetDisplayText();
        var textSize = g.MeasureString(text, _textFont);
        var location = new PointF((Width - textSize.Width) / 2, (Height - textSize.Height) / 2);

        g.DrawString(text, _textFont, _textBrush, location);
    }

    private string GetDisplayText()
    {
        return VisualMode switch
        {
            ProgressBarDisplayMode.Percentage => $"{(int)((Value - Minimum) / (float)(Maximum - Minimum) * 100)}%",
            ProgressBarDisplayMode.CurrProgress => $"{Value}/{Maximum}",
            ProgressBarDisplayMode.TextAndPercentage =>
                $"{_customText}: {(int)((Value - Minimum) / (float)(Maximum - Minimum) * 100)}%",
            ProgressBarDisplayMode.TextAndCurrProgress => $"{_customText}: {Value}/{Maximum}",
            _ => _customText,
        };
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _textBrush.Dispose();
            _progressBrush.Dispose();
            _textFont.Dispose();
        }

        base.Dispose(disposing);
    }

    public enum ProgressBarDisplayMode
    {
        NoText,
        Percentage,
        CurrProgress,
        CustomText,
        TextAndPercentage,
        TextAndCurrProgress,
    }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions