How do I put text on ProgressBar?

I have written a no blinking/flickering TextProgressBar

You can find the source code here: https://github.com/ukushu/TextProgressBar

enter image description here

WARNING: It's a little bit buggy! But still, I think it's better than another answers here. As I have no time for fixes, if you will do sth with them, please send me update by some way:) Thanks.

Samples:

enter image description here enter image description here no blinking/flickering TextProgressBar

no blinking/flickering TextProgressBar enter image description here enter image description here


You will have to override the OnPaint method, call the base implementation and the paint your own text.

You will need to create your own CustomProgressBar and then override OnPaint to draw what ever text you want.

Custom Progress Bar Class

namespace ProgressBarSample
{

public enum ProgressBarDisplayText
{
    Percentage,
    CustomText
}

class CustomProgressBar: ProgressBar
{
    //Property to set to decide whether to print a % or Text
    public ProgressBarDisplayText DisplayStyle { get; set; }

    //Property to hold the custom text
    public String CustomText { get; set; }

    public CustomProgressBar()
    {
        // Modify the ControlStyles flags
        //http://msdn.microsoft.com/en-us/library/system.windows.forms.controlstyles.aspx
        SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Rectangle rect = ClientRectangle;
        Graphics g = e.Graphics;

        ProgressBarRenderer.DrawHorizontalBar(g, rect);
        rect.Inflate(-3, -3);
        if (Value > 0)
        {
            // As we doing this ourselves we need to draw the chunks on the progress bar
            Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height);
            ProgressBarRenderer.DrawHorizontalChunks(g, clip);
        }

        // Set the Display text (Either a % amount or our custom text
        int percent = (int)(((double)this.Value / (double)this.Maximum) * 100); 
        string text = DisplayStyle == ProgressBarDisplayText.Percentage ? percent.ToString() + '%' : CustomText;            

        using (Font f = new Font(FontFamily.GenericSerif, 10))
        {

            SizeF len = g.MeasureString(text, f);
            // Calculate the location of the text (the middle of progress bar)
            // Point location = new Point(Convert.ToInt32((rect.Width / 2) - (len.Width / 2)), Convert.ToInt32((rect.Height / 2) - (len.Height / 2)));
            Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2), Convert.ToInt32((Height / 2) - len.Height / 2)); 
            // The commented-out code will centre the text into the highlighted area only. This will centre the text regardless of the highlighted area.
            // Draw the custom text
            g.DrawString(text, f, Brushes.Red, location);
        }
    }
}
}

Sample WinForms Application

using System;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;

namespace ProgressBarSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // Set our custom Style (% or text)
            customProgressBar1.DisplayStyle = ProgressBarDisplayText.CustomText;
            customProgressBar1.CustomText = "Initialising";
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            customProgressBar1.Value = 0;
            btnStart.Enabled = true;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnReset.Enabled = false;
            btnStart.Enabled = false;

            for (int i = 0; i < 101; i++)
            {

                customProgressBar1.Value = i;
                // Demo purposes only
                System.Threading.Thread.Sleep(100);

                // Set the custom text at different intervals for demo purposes
                if (i > 30 && i < 50)
                {
                    customProgressBar1.CustomText = "Registering Account";
                }

                if (i > 80)
                {
                    customProgressBar1.CustomText = "Processing almost complete!";
                }

                if (i >= 99)
                {
                    customProgressBar1.CustomText = "Complete";
                }
            }
                        
            btnReset.Enabled = true;


        }

   
    }
}

AVOID FLICKERING TEXT

The solution provided by Barry above is excellent, but there's is the "flicker-problem".

As soon as the Value is above zero the OnPaint will be envoked repeatedly and the text will flicker.

There is a solution to this. We do not need VisualStyles for the object since we will be drawing it with our own code.

Add the following code to the custom object Barry wrote and you will avoid the flicker:

    [DllImportAttribute("uxtheme.dll")]
    private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);

    protected override void OnHandleCreated(EventArgs e)
    {
        SetWindowTheme(this.Handle, "", "");
        base.OnHandleCreated(e);
    }

I did not write this myself. It found it here: https://stackoverflow.com/a/299983/1163954

I've testet it and it works.