Text inside a progressbar

Master Zero

Well-known member
Joined
Sep 10, 2005
Messages
51
Programming Experience
Beginner

Can anyone tell me how to put text inside a progressbar?

For example, I want to embed the current percentage value of the progressbar within it.

Thanks in advance!
 
so when I give it another value the same memory is used again
No, that is not correct.
if it's wrong I have an awful lot of memory leaks in my programs
Not necessarily, .Net is managing the memory usage for you as it always have done and as it was designed to do, it does this through something called Garbage Collector (GC), but as mention the tasks of the GC is very specific, and releasing locked resources cleanly is not one of them, this is what you have to write code for by implementing IDisposable where you take care of that business, and consumer of the class is obligated to call the Dispose method when they are done using it. The standard of having such an interface makes things very easy for programmer when they need to shut down an object because they always know what method to call - need to clean up? call Dispose! Always. And since this is a programming standard you only need to check if an object has a Dispose method to know if you need to call it, if it has a Dispose method then you must use it. From the other side of the table, if you're writing a class and see that there are objects that need to be cleaned up before the consumer should dereference it, then the solution is given, implement IDisposable! This will simply tell consumer that she must call Dispose before leaving the object instance.
can you please demonstrate the solution or give a simple example?
For example in your Graphics property setter:
VB.NET:
If m_graphics IsNot Nothing Then m_graphics.Dispose()
In ShowPercentage method:
VB.NET:
strFormat.Dispose()
reg1.Dispose()
reg2.Dispose()
 
Hey,

Thnx again for your reply :)

I added the dispose for these regions in my code, but am unsure where to place the strFormat dispose. Between version 1.0.5 and 1.0.6 I changed where the strFormat is set, and also changed it's scope. (added current version as attachment)

Do I still need to dispose this object (if yes where?), or do I leave it as it is now?

Cheers
BN
 

Attachments

  • pbarpercentage108.txt
    15.3 KB · Views: 52
I added the dispose for these regions in my code, but am unsure where to place the strFormat dispose. Between version 1.0.5 and 1.0.6 I changed where the strFormat is set, and also changed it's scope. (added current version as attachment)

Do I still need to dispose this object (if yes where?),
What you have to find out is
- where and when is a object created?
- where does you code release last reference to the object?
Knowing this information you can find any code path where an object may slip without you disposing it.

Using the VS search tool is helpful here, highligh the class field and select "Find All References", you can now see a list of all code lines where this field variable is used, they are either read operations or assignment operations. All assignments are a places where you must dispose the previous instance (if no other part of code is also holding a reference to same object, this would complicate things :)). In addition you need to dispose when explicitly called for.

Try this with the m_strFormat field, you get a long list of read operations and only one assignment, which is the declaration where also a new instance is assigned. So here you only need to dispose it when consumer calls Dispose method.

Try the same with the m_graphics field, only 3 references is now found; the declaration (no assignment), 1 read operation, 1 assignment operation (the property setter). In property setter you must dispose the previous instance (as per my previous post). In addition you need to dispose it when consumer calls Dispose method.

About the Dispose method, your base class here (Control) implements IDisposable, so you have a overrides for Dispose(disposing), this is ok, you are also here Disposing the Graphics which is correct and calling the base. As implied above you need to add Dispose for m_strFormat also in this method. There is also the possibility of handling the Dispose event instead of overriding.

Your Dispose() overload is not needed, you should remove it because it does not fit in the IDisposable pattern. Overloads is only called if the object cast as this specific type, otherwise the base method is called. While your code in this method in this case probably is correct and most likely doesn't differ from the base functionality, there is only room for errors doing this. The base Dispose() will call your Dispose(disposing) override.
 
Hey,

That was very helpful! I changed the following things:
VB.NET:
        Private Sub setStringFormat()
            If m_strFormat IsNot Nothing Then m_strFormat.Dispose() ' added this
            m_strFormat = New StringFormat ' added this

            ' Determine the horizontal alignment
            Select Case Me.PercentageAlign
             ...
        End Sub

VB.NET:
        Protected Overridable Property Graphics() As Graphics
            Get
                Return m_graphics
            End Get
            Set(ByVal value As Graphics)
                If Me.Graphics IsNot Nothing Then Me.Graphics.Dispose() ' added this
                m_graphics = value
            End Set
        End Property

VB.NET:
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Me.AutoUpdatePercentage = False
            If disposing Then
                Me.Graphics.Dispose()
                m_strFormat.Dispose() ' added this
            End If
            MyBase.Dispose(disposing)
        End Sub

(And removed the public Dispose() sub)

This is correct now right? :)

A shame I can't give you reputation 2x in a row :p
 
If m_strFormat IsNot Nothing Then m_strFormat.Dispose() ' added this
m_strFormat = New StringFormat ' added this
Why did you add this? Why do you need to create a new StringFormat instance here?
This is correct now right?
The other parts is now fine.
A shame I can't give you reputation 2x in a row
Thanks for the points :)
 
Hey,

If m_strFormat IsNot Nothing Then m_strFormat.Dispose() ' added this
m_strFormat = New StringFormat ' added this
Why did you add this? Why do you need to create a new StringFormat instance here?
I was a little confused there, but I know what I did wrong :eek:

I've send a new version to the code project, so it'll probably show up shortly :)

There is an issue with displaying the percentage though. Sometimes (especially when increasing the value fast), two numbers successive get overlayed on each other for a while. Any idea what's causing this?

Cheers
BN
 
That is because you force drawing when value is changed. This means the control in some cases has not repainted, and you have painted on top of that. You can remove it because you get a WM_PAINT when value changes. If you didn't you could instead have asked for a repaint with Invalidate/Update/Refresh.
 
Hey,

I changed
VB.NET:
If Me.PercentageVisible And Me.AutoUpdatePercentage Then Me.ShowPercentage()
To
VB.NET:
If Me.PercentageVisible And Me.AutoUpdatePercentage Then Me.Invalidate()
In Set of both Value and Percentage properties, like you suggested, and it seems to be working :)

The only remaining issue I can come up with now is that when using vista, the bar doesn't immediately fill up the correct part, but slides towards it over a short period of time. The regions however immediately match the value, and therefore do not correspond with the filled area.

Anyone an idea how this can be solved? If not, just a small issue really, but would be nice if it was solved :)
 
like you suggested
So removing the line as I suggested didn't work??
the bar doesn't immediately fill up the correct part, but slides towards it over a short period of time.
Not really, it uses a thread internally to increase the bar smoothly from previous to next value.
 
So removing the line as I suggested didn't work??
Will WndProc be called when the value or percentage is set then? (also on XP?)

Not really, it uses a thread internally to increase the bar smoothly from previous to next value.
Ok. Is there any (doable) way of interacting with this thread? :)
 
Back
Top