mathgenius
mathgenius

Reputation: 513

DrawString graphics dissappearing

I am trying to draw a string over a progress bar as outlined here and here. The progress bar is located on one of a series of tab pages in my tab control.

This is my code:

int percent = 55;
using (Graphics gr = progressBar1.CreateGraphics())
{
gr.DrawString(percent.ToString() + "%",
SystemFonts.DefaultFont,
Brushes.Black,
new PointF(progressBar1.Width / 2 - (gr.MeasureString(percent.ToString() + "%", SystemFonts.DefaultFont).Width / 2.0F), progressBar1.Height / 2 - (gr.MeasureString(percent.ToString() + "%", SystemFonts.DefaultFont).Height / 2.0F)));
}

It doesn't work. After fiddling with a timer:

this.timer1.Enabled = true;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

private void timer1_Tick(object sender, EventArgs e)
{
    progressBar1.PerformStep();
    System.Threading.Thread.Sleep(100);
    progressBar1.Refresh();
    int percent = (int)(((double)(progressBar1.Value - progressBar1.Minimum) / (double)(progressBar1.Maximum - progressBar1.Minimum)) * 100);
    progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
}

and just some simple:

private void button1_Click(object sender, EventArgs e)
{
    DrawProgress(); //this just calls the a method to do the DrawString
}

I found out it does draw the string but after switching to another tab and back the string is no longer visible/there.

I even switched "gr" to "progressBar1.CreateGraphics()" and removed the "using" statement to see if it was just disposing of the string, but even with:

progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", SystemFonts.DefaultFont, Brushes.Black, new PointF(progressBar1.Width / 2 - (progressBar1.CreateGraphics().MeasureString(percent.ToString() + "%", SystemFonts.DefaultFont).Width / 2.0F), progressBar1.Height / 2 - (progressBar1.CreateGraphics().MeasureString(percent.ToString() + "%", SystemFonts.DefaultFont).Height / 2.0F)));

I have the same problem.

Upvotes: 0

Views: 499

Answers (1)

Jeroen van Langen
Jeroen van Langen

Reputation: 22073

I think, the best solution is: You should derive from ProgressBar and implement your own Paint handler.

Here's an example: (tested)

// Custom paint progressbar
public class ProgressBarWithTitle : ProgressBar
{
    private Brush _barBrush;


    public ProgressBarWithTitle()
    {
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

        _barBrush = new SolidBrush(this.ForeColor);

    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        var rect = new RectangleF(0, 0, (float)(this.Width * (Value - Minimum) / Maximum), this.Height);
        e.Graphics.FillRectangle(_barBrush, rect);

        var valueString = base.Value.ToString() + "%";

        var textSize = e.Graphics.MeasureString(valueString, SystemFonts.DefaultFont);

        e.Graphics.DrawString(
            valueString,
            SystemFonts.DefaultFont,
            Brushes.Black,
            new PointF(
                (Width / 2) - ((int)textSize.Width / 2),
                (Height / 2) - ((int)textSize.Height / 2)));
    }


}

The only problem is, that you'll have to draw the progressbar yourself.

Upvotes: 2

Related Questions