How to clear controls from a form - Help Needed

S

Siv

I have a form that I programmatically generate some check boxes and labels on.
Later on when I want to draw the form with different data I want to clear
the previously created items and then put some new ones on.

In my code I am doing the following:

For Each ctrl In tpMain.Controls
If TypeOf (ctrl) Is CheckBox Then
If ctrl.Name.StartsWith("chkS") Then
ctrl.Visible = False
ctrl.Dispose()
End If
End If
End if
Next

What I am finding however is that in some cases controls that I know have
been affected by the above loop are staying on the form and not being made
invisible and then being disposed.

Is there a sure fire method of removing the controls rather than the dispose
method which presumably is not always removing the control for whatever
reason??

Siv
 
R

Rich P

It would be much easier/simpler/reliable to have an extra form with the
extra controls. When a user needs to use the other set of controls -
instead of creating a whole new set of controls just bring up the extra
form and hide the main form - or if it even matters don't do anything
with the main form. Just leave it running.

Rich
 
S

Siv

I can't do that because the amount of check boxes differs dramatically
between redraws, there isn't a fixed layout. On one set of data I may only
need to show 2 check boxes on another ther may be 20 or 30. I am trying to
avoid the overhead of having thousands of controls on the forma nd only
create them as I need them and then when I have finished with them destroy
them again.

The problem i think is tha the dispose method doesn't always decide to
dispose when I want it to and is probably waiting for the system to quieten
down before actioning the request.

I really need a Ctrl.delete type comand.

Siv
 
L

Lloyd Sheen

Siv said:
I can't do that because the amount of check boxes differs dramatically
between redraws, there isn't a fixed layout. On one set of data I may only
need to show 2 check boxes on another ther may be 20 or 30. I am trying to
avoid the overhead of having thousands of controls on the forma nd only
create them as I need them and then when I have finished with them destroy
them again.

The problem i think is tha the dispose method doesn't always decide to
dispose when I want it to and is probably waiting for the system to quieten
down before actioning the request.

I really need a Ctrl.delete type comand.

Siv

Try this:

Create a panel onto which you will place your dynamic controls.

When you are finished with those controls, you should have a variable
for the original panel. Use the Clear method to get rid of all the
controls you created dynamically.

You now should have a blank panel upon which you can add controls with
new info.

Hope this helps
LS
 
S

Stephany Young

For _i = tpMain.Controls.Count - 1 To 0 Step -1
Dim _ctrl = tpMain.Controls(_i)
If TypeOf (_ctrl) Is CheckBox AndAlso _ctrl.Name.StartsWith("chkS") Then
tpMain.Controls.RemoveAt(_i)
_ctrl.Dispose()
End If
Next
 
S

Siv

Lloyd,
Thanks for your response, these controls are already on a TabPage control
called tpMain.

When you say perform a clear, is that a method of the panel itself. Will
that clear all controls? There are a number of controls which are placed on
the TabPage at design time, would they be destroyed as well?

Interesteing idea though, I could certainly add a panel onto the TabPage in
the area where I want to display the check boxes and only add the controls
that are dynamically created to that panel.

Cheer,

Siv
 
S

Siv

Stephany,
Thanks for your reply. Can you explain why the additional command

tpMain.Controls.RemoveAt(_i)

will do the trick where just doing the dispose on its own does not?

I appreciate you gave me the answer, but I try to learn from my questions
here. Don't worry if you are too busy to reply, but if you do have time I
would appreciate it.

Siv
 
S

Stephany Young

Your problem was that, although you were 'disposing' the control, you were
not removing it from tpMain's collection of controls. Therefore you end up
with 'phantom' controls in tpMain's control collection.

Others might argue to the contrary, but I believe that the Dispose method of
a CheckBox control does nothing special, and it certainly will not remove
itself from it's parent collection.

Therefore the code can be further simplified to:

For _i = tpMain.Controls.Count - 1 To 0 Step -1
Dim _ctrl = tpMain.Controls(_i)
If TypeOf (_ctrl) Is CheckBox AndAlso _ctrl.Name.StartsWith("chkS") Then
tpMain.Controls.RemoveAt(_i)
Next

To save you asking, the reverse loop is to ensure that iterating on the
control collection is still viable even when one or more of the iteration
actually removes an element.
 
S

Siv

Stephany,

Thanks for clarifying, clearly I thought that to dispose of a control would
by inference remove it from the tpMain collection of controls. It's the old
story "never assume".

Thanks for your help.

Siv
 
L

Lloyd Sheen

Siv said:
Lloyd,
Thanks for your response, these controls are already on a TabPage control
called tpMain.

When you say perform a clear, is that a method of the panel itself. Will
that clear all controls? There are a number of controls which are placed on
the TabPage at design time, would they be destroyed as well?

Interesteing idea though, I could certainly add a panel onto the TabPage in
the area where I want to display the check boxes and only add the controls
that are dynamically created to that panel.

Cheer,

Siv

Clear will clear all controls on the container (panel) so you would
loose other "non-dynamic" controls. Putting a panel on the tab page
would certainly work.

LS
 
S

Siv

Lloyd,
I am just trying Stephany's method as it involves less changes than yours,
but if her method doesn't solve teh problem I'll redesign the form slightly
and implement your idea.

Thanks again for your help.

Siv
 
C

Cor Ligthert[MVP]

Siv,

Disposing is not a removing method or whateverf, it is just telling the GC
that it "can be" ready to clear up, like the GC does that automaticly when
it is really needed. Dispose is meant to put it at the garbage. As anology,
some people are the whole day busy with cleaning up there desktop (putting
it in the trash bin, which still will not be direct emptied), others do that
once a day or/and some when that is needed.

As it is about forms, you can see in your designer part of the class
(versions before 2005 normal in the class) the implementing of IDisposable
of a form.

As long as an object is referenced by something (like on a form with
controls.add) it will not be cleared as long as that has a reference,
whatever other method you call (including dispose), mostly is that by clear
them all in one time or by removing them one by one.

Cor


Siv said:
Stephany,

Thanks for clarifying, clearly I thought that to dispose of a control
would
by inference remove it from the tpMain collection of controls. It's the
old
story "never assume".

Thanks for your help.

Siv
 
J

Jack Jackson

Cor,

I'm sure it is useless to argue with you, but it is misleading to say
that the purpose of Dispose is to tell the GC that the object " 'can
be' ready to clear up".

The purpose if Dispose is to release unmanaged resources. For
Controls, that would mostly be the Windows handle for the associated
Windows control. If you fail to call Dispose for a Control that has
allocated a Windows handle, then the handle might no be freed for a
very long time, and if you do this enough times you might run out of
Windows handles.
 
C

Cor Ligthert [MVP]

Jack,

Absolute true, I had it first in my message but was afraid that it would
create to much confusion (and discussion). I normally try to write that part
exactly like you do, and it is very important in the case there are
unmanaged resources used. Which is AFAIK by instance not the fact "in"
controls. (but can be used in objects that controls are using).

I have seen it so much written in the context like I did now, so I did that
a bit like that to avoid a discussion. Normally I don't use that because it
is for me really a minor aspect to take action to clear 100bytes memory a
little bit quicker while I have 1Gb not used.

Cor
 
C

Cor Ligthert [MVP]

Jack,

Maybe should I have added this piece of code that is created by most
designers.
Which AFAIK is done by instance at every close of a form.

\\\
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
///

Cor
 
C

Cor Ligthert [MVP]

Jack,

And the last one I hope, I have forever discussion with people who tell that
you should call the method dispose as soon as that method is derived from
components (which has a dispose method).

It is simple not true, a simple dataset is an array of references, nothing
more and has not any unmanaged resource, but it derives from components.

http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

As well is often forgotten that like "using" the method "close" often calls
the dispose (like by the dataconnection).

Cor
 
C

Cor Ligthert [MVP]

Jack,

Should call the method is derived from compone I hope, I has a
discussion as a dispose as soon as the last one I has that you should
call that you should call that you should call that method dispose as
soon with people who tell that method dispose method). And that method
is derived from compone I have forever dispose as a discussion with
people who tell that you should call that metthod.

Nothing more and has nothing more an array of resource, a simple dataset
it derives from components. It is simple dataset is any unmanaged
references, not true, a simple dataset is simple dataset it derives from
components. It it derives from components. It is and has not true, but
is simple not trrue,

http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

Dataconnection). As well is often forgotten forgotten the
dataconnection). As well is often forgotten forgotten forgotten
forgotten the dispose (like by that like "using" that like by that like
by the method "close (like by the dataconnect

Cor

In bericht "jack
jackson" <jjack jack jackson" <[email protected]> schreef in
bericht "jack jack
(e-mail address removed)>.
 
S

Siv

Stephany,
Your method worked a treat and my form now looks as it should between each
redraw. I noticed the conversation below between Cor and Jack and that is
flushing out some interesting debate about the merits of dispose.

I definitely agree with Jack's assertion that you really do need to include
the dispose method, otherwise on a form like mine where the same tab page is
being used over and over with potentially thousands of controls used each
time the tab page is populated with checkboxes would lead to some for of
resource problem if run long enough.

Thanks again for your help, the program now works as it should and I have
learnt something new.

Siv
 
S

Siv

Cor,
Thanks for your help on this. My mistake as mentioned above when Stephany
put me straight was that I asumed that if the dispose method was called, that
would effectively make the parent (in this case a tabpage) automatically
remove the control from its collection.

Now I underdtand that this isn't the case my understanding of how Dispose
operates is improved. Thanks for your help with this.

Siv
--
Martley, Near Worcester, UK


Cor Ligthert said:
Siv,

Disposing is not a removing method or whateverf, it is just telling the GC
that it "can be" ready to clear up, like the GC does that automaticly when
it is really needed. Dispose is meant to put it at the garbage. As anology,
some people are the whole day busy with cleaning up there desktop (putting
it in the trash bin, which still will not be direct emptied), others do that
once a day or/and some when that is needed.

As it is about forms, you can see in your designer part of the class
(versions before 2005 normal in the class) the implementing of IDisposable
of a form.

As long as an object is referenced by something (like on a form with
controls.add) it will not be cleared as long as that has a reference,
whatever other method you call (including dispose), mostly is that by clear
them all in one time or by removing them one by one.

Cor
 
S

Siv

Jack,
Thanks for your response on this. My reason for using the dispose method
was just that. As this one tab page gets used all day by users clicking
items in a treeview to the left side of the form causing the application to
generate potentially 20 or 30 checkboxes relating to the data that the
selected item in the treeview represents. The user then interacts selecting
items using the checkboxes and then saves the results back to the database.
I then clear the check boxes I have dynamically created ready for the next
item that the user may select.

My biggest worry with this was that over a day's usage if I didn't dispose
of the controls, as you said, I would end up with the system's resources
being exhausted.

I am a VB developer since VB1 and I clearly remember this being an issue
particularly when running apps on Windows 3.1 which had a much smaller
resource stack than we have now under XP and you could quite easily exhaust
it. I remember apps that wold suddenly stop drawing parts of the screen
because the system had run out of memory to keep tabs on all the controls on
your form.

Happy days!

Siv
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top