C#: Overriding OnPaint on ProgressBar not working?

Svish picture Svish · Oct 4, 2009 · Viewed 14.3k times · Source

Was thinking it should be pretty easy to create a ProgressBar that drew some text upon itself. However, I am not quite sure what is happening here...

I added the following two overrides:

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        base.OnPaintBackground(pevent);
        var flags = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;
        TextRenderer.DrawText(pevent.Graphics, "Hello", Font, Bounds, Color.Black, flags);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        var flags = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter | TextFormatFlags.SingleLine | TextFormatFlags.WordEllipsis;
        TextRenderer.DrawText(e.Graphics, "Hello", Font, Bounds, Color.Black, flags);
    }

However, I get no text, and the methods doesn't even seem to be called. What is going on here?


Update: Thanks to the two answers so far, I have gotten it to actually call the OnPaint by using SetStyle(ControlStyles.UserPaint, true), and I have gotten it to draw the text in the right place by sending in new Rectangle(0, 0, Width, Height) instead of Bounds.

I do get text now, but the ProgressBar is gone... and the point was kind of to have the text on top of the ProgressBar. Any idea how I can solve this?

Answer

Christian Westman picture Christian Westman · May 21, 2010

You could override WndProc and catch the WmPaint message.

The example below paints the Text property of the progressbar in its center.

public class StatusProgressBar : ProgressBar
{
    const int WmPaint = 15;

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        switch (m.Msg)
        {
            case WmPaint:
                using (var graphics = Graphics.FromHwnd(Handle))
                {
                    var textSize = graphics.MeasureString(Text, Font);

                    using(var textBrush = new SolidBrush(ForeColor))
                        graphics.DrawString(Text, Font, textBrush, (Width / 2) - (textSize.Width / 2), (Height / 2) - (textSize.Height / 2));
                }
                break;
        }
    }
}