Somebody asked how to use my transparent label on top of a ProgressBar control, since it disappeared when the progress bar changed its state. I had a look at it, but the transparent label wasn’t getting any notification of changes, even when I hooked into the WndProc method. So I wondered if it would be possible to sub-class the ProgressBar control and write some text on top of it that way. And that seems to work OK, as shown below.
Update – I’ve fixed the flickering
Update 2 – It now picks up the text colour from the ForeColor property
Update 3 – Should now work on Windows XP
Update 4 – Now lets you specify the font used for the text
using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System; namespace WinFormControls { public class TextProgressBar : ProgressBar { protected override CreateParams CreateParams { get { CreateParams result = base.CreateParams; if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6) { result.ExStyle |= 0x02000000; // WS_EX_COMPOSITED } return result; } } protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 0x000F) { using (Graphics graphics = CreateGraphics()) using (SolidBrush brush = new SolidBrush(ForeColor)) { SizeF textSize = graphics.MeasureString(Text, Font); graphics.DrawString(Text, Font, brush, (Width - textSize.Width) / 2, (Height - textSize.Height) / 2); } } } [EditorBrowsable(EditorBrowsableState.Always)] [Browsable(true)] public override string Text { get { return base.Text; } set { base.Text = value; Refresh(); } } [EditorBrowsable(EditorBrowsableState.Always)] [Browsable(true)] public override Font Font { get { return base.Font; } set { base.Font = value; Refresh(); } } } }
17 comments:
Could you please explain me how do you use/implement this text on ProgressBar?
I appreciate your help.
Thanks.
Just copy the code to a new C# file and use the TextProgressBar class instead of the ProgressBar class in your application.
Great contro! but is there a solution for the flickering?
Indeed there is, I figured it out and it flickers no more
Excellent! works perfectly!
Is there a also a way to change the text color?
There is now, just use the ForeColor property
Hi,
Useful mod, works fine on Win7, but on win XP the label is not visible?? Any ideas?
Danny
Hi,
Great Mod. Works Fine on Win 7 PCs.
Unfortunately it does not work on XP machines, the label is not visible.
Any ideas why? Perhaps the Win7 Visual styles??
Cheers
Danny
Unfortunately I don't have access to an XP machine to investigate. Maybe the progress bar is implemented differently there whcih is causing the problem? Maybe try removing the CreateParams as well to see if that's causing the problem (might start flickering a bit though)
Hi,
Sorry for the double post. Feel free to delete the first one.
You were right about the CreateParams.
I did a bit a trawling on the net and read somewhere that simply apply the command to Vista upwards.
http://stackoverflow.com/questions/1282911/windows-form-paints-repeatedly-in-xp-but-not-in-vista
protected override CreateParams CreateParams
{
get
{
CreateParams result = base.CreateParams;
if (Environment.OSVersion.Platform == PlatformID.Win32NT
&& Environment.OSVersion.Version.Major >= 6)
{
result.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
}
return result;
}
}
great code , it worked perfectly. i was able to figure out how to change the color of the text half way through using get/set on ForeColor... i am new to C Sharp so i am learning, but i can't seem to figure out how to make the text font BOLD or a Different font type as well???
You need to change the reference to SystemFonts.DefaultFont to your own choice of font. I'll add it as a property of the control at some point, but I'm going to be busy for the next few days
Now has a Font property
Thanks for this great control. It helped me a lot. In my project I had about 10 progressbars in different places showing progress of very long operations. Just changed reference in design.cs and have Text property! Awesome piece of code!
Thanks for this great control. It helped me a lot as well
Thanks for the code. But somehow, when I test this on a loop from 1 to 10000, the text gets to display 10000 before the progress bar reaches to its maximum. Here is the simple code that I have:
ProgressBar1.Minimum = 0;
ProgressBar1.Value = 0;
ProgressBar1.Maximum = 10000;
ProgressBar1.Text = "";
for (int iIdx = 1; iIdx <= ProgressBar1.Maximum; iIdx++)
{
ProgressBar1.Text = "Item " + iIdx.ToString() + " of " + ProgressBar1.Maximum.ToString() + " ...";
ProgressBar1.Value = iIdx;
}
For hundreds of itertaions at the end, the text says Item 10000 of 10000 ... while the progress bar clearly has not finished yet. Something is really not working.
Also, I have seen that in some compilers versions, it is complaining about the overridden Text property. The compiler is throwing an error saying that the Text property cannot be overriden because it is not abstract, virtual etc. Just thought putting this out ther.
To be honest it years since I've looked at this code. You may want to put an Application.ProcessMessages() in your loop to ensure everything is getting repainted which might fix it
Post a Comment