Wierd For...Each behavior

  • Thread starter Thread starter Tom
  • Start date Start date
T

Tom

This is very strange: I have a Windows Form with a Panel on it. In that
panel I dynamically (at run time) create some labels, as so:

for i=1 to x
dim ctlNew as New Label()
with ctlNew
.Name="Whatever" & trim(cstr(i))
.Text=.Name
.Visible=True
... etc etc etc ...
end with
MyPanel.Controls.Add(ctlNew)

This shows up fine when the form is displayed. However, I also have a reset
button on the form, which goes thru and destroys the labels, as such:

dim ctl as Control
for each ctl in MyPanel.Controls
if typeof ctl is Label then
ctl.text=""
ctl.visible=False
ctl.Dispose()
end if
next

OK, here is the WIERD thing: The For...Each loop only seems to pick up the
EVEN or ODD numbered controls! It skips some of the controls (i.e. the odd
ones).... if I rerun the loop about three times, one right after the other,
it will finally pick up all the controls and get rid of them.

I -think- the code is correct - I even added a ctl=Nothing before and/or
after the ctl.Dispose(), but it didn't help. The For...Each loop just seems
the skip some of the label controls during its run. I am baffled ... even
though it is probably something dumb that I am doing.

Anyone got any ideas on this?

Tom
 
Tom,
dim ctl as Control
for each ctl in MyPanel.Controls
if typeof ctl is Label then
ctl.text=""
ctl.visible=False
ctl.Dispose()
end if
next
I think that the collections in the for each loop is changed in the the for
each loop
I think that nicer is
For i = Me.Controls.Count To 0 Step -1
Dim ctl As Control
it typeof ctl is Label then
Me.Controls.Remove(ctl)
Next
I hope this helps
Cor
 
Why don't you just set the labels to nothing? Dispose is called by the GC.
All you really have to do it kill your reference to the object. Let the GC
take care of the rest.
 
Isn't Controls.Count a one-based index? I think it should be:

For i = Me.Controls.Count -1 To 0 Step -1
....
 
Cor said:
Tom,
I think that the collections in the for each loop is changed in the the for
each loop
I think that nicer is
For i = Me.Controls.Count To 0 Step -1
Dim ctl As Control
it typeof ctl is Label then
Me.Controls.Remove(ctl)
Next
I hope this helps
Cor

It doesn't help when you post bad code that doesn't work, despite your good
intentions.

You also might want to learn when to use While or Do loops instead of
misusing a For loop.
 
Yea, stupid me, I just figured this out when everyone replied. Sheesh, I
should have seen that. Anyway, I'll go in reverse and remove the items that
way. Thanks.

Tom
 
Jack.
Yes I mistyped the -1 but that can every programmer with a little expirience
see.
Robert was so kind to tell that.

But show that you can do it better, send a good working code in this
situation with the do while loop.
Cor
 
Scott Meddows said:
Why don't you just set the labels to nothing? Dispose is called by the GC.
All you really have to do it kill your reference to the object. Let the GC
take care of the rest.

Because that won't work for controls. Controls are referenced by their
container, so it doesn't matter whether you set all code references to
nothing: the container will still hold a reference until you remove the
control or the container itself.
 
Then you'd have to loop through a loop and do the
container.controls.remove(YourForEachLoopControl) ?
 
Cor said:
Jack.
Yes I mistyped the -1 but that can every programmer with a little expirience
see.
Robert was so kind to tell that.

Apparently, you fail to see why your code won't work. Here's a hint: the
if statement always evalutes to false.
But show that you can do it better, send a good working code in this
situation with the do while loop.

Maybe you should post code that works before you command others to do so,
padawan.
 
Jack Spry said:
You also might want to learn when to use While or
Do loops instead of misusing a For loop.

If you have a working solution, feel free to post it. Do not shout at other
people there if you do not contribute to the ng.
 
Hi,
The example code was full of typing errors, it was ment as an example.
But because there are maybe real beginners looking to it, who can not
evaluate that, under the typed example from what I think that will work on a
form.
For i = Me.Controls.Count To 0 Step -1
Dim ctl As Control
it typeof ctl is Label then
Me.Controls.Remove(ctl)
There is not even an if in this example but an it..
\\\\\\
Dim i As Integer
For i = Me.Controls.Count - 1 To 0 Step -1 'As something with what I
always must think to Armin
Dim ctrl As Control = Me.Controls.Item(i)
If TypeOf ctrl Is Label Then
Me.Controls.Remove(ctrl)
End If
Next
/////
Cor
 
Hi Jack Padawan,
There is no If in it, that is also a typing error, but don't give critique
Come with that nice example with a "do while loop".
We are waiting
Cor
 
Scott Meddows said:
Then you'd have to loop through a loop and do the
container.controls.remove(YourForEachLoopControl) ?

Yes, you need to remove the controls from the container, as well as any
event handlers that were attached, if necessary. There are several ways to
do that, depending on the circumstances. Since removing controls
dynamically changes the container, it would be best not to use a looping
structure such as ForEach to iterate over the contents, since this is
pulling the rug out from under yourself.
 
Come with your Example, but we will see, tomorrow there is nothing and the
day after tomorrow again
 
Hi Jack,

Shame you're having a bad week. Still, you're always welcome to come here
and inappropriately vent your spleen. We like to be helpful. If we can't do
that then we're happy to be punchbags for people with a bit a of anger and
frustration.

Hope this helps.

NOT

Fergus
 
Yea, stupid me, I just figured this out when everyone replied. Sheesh, I
should have seen that. Anyway, I'll go in reverse and remove the items that
way. Thanks.

Hi,

Yeah, that would make sence :-) Never mind.

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Slow internet connection?
Having problems with you job?
You're marriage is on the rocks?
You can't sleep at night?
You have a drink and drugs addiction?
You are sexually impotent?
Then enable Option Strict!
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
Still here Jack ?

|| Yes, you need to remove ..... blah, blah, .....
|| ..... best not to use a looping structure .....
|| since this is pulling the rug out from under yourself.

And we've <yet> to see your code contribution. Don't just criticise and talk
about it. Post the code. It's no challenge for a man of your calibre is it?

Fergus
 
Come with your Example, but we will see, tomorrow there is nothing and the
day after tomorrow again

Hi there,

Technically speaking what Jack says is correct. But that doesn't
account for the manner in which he is conducting himself at the moment.

Jack, please notice that this is a newsgroup for people wanting to learn
VB.NET as well as for people wanting to pool their knowledge of it. Fair
enough we all have a pop at each other now and then, but there is usually a
good reason for it, remember that when people post code it hasn't always
been tested, it's just been posted to show an example, this is called pseudo
code. So calm down a little please, you will only make yourself unpopular
here.

The problem is solved now anyway, so why the need to argue?

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Slow internet connection?
Having problems with you job?
You're marriage is on the rocks?
You can't sleep at night?
You have a drink and drugs addiction?
You are sexually impotent?
Then enable Option Strict!
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
Back
Top