Skip to content

Here's a .NET9 version #3

@pmeems

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,
    }
}

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