Controls.Remove not removing ALL controls.

G

Greg

I have the following code the dynamically adds a specific number of controls.

for x as integer = 1 to 10
Dim btn as Windows.Forms.Button = New Windows.Forms.Button
btn.Name = "btn" & x
btn.Text = "Test" & x
controls.add(btn)
next x

This results in 10 buttons appearing on the screen. I've excluded the
location info.

Now, in my program the number of buttons varies based on the size of the
form. If the form is decreased in size I will display less buttons. But,
before I update the buttons on the screen, I just remove them all before
refreshing the screen with new buttons.

I use the following code to remove the buttons on the screen.

For Each btn as Windows.Forms.Button in Me.Controls
controls.remove(btn)
Next

In my example, I have 48 buttons displayed on the screen. When the Remove
code above runs it does not delete/remove all of the buttons. If I replace
the controls.Remove command with a debug.print command I can see that every
button is found in the loop. But, when I replace the debug.print and put the
conttols.remove back in all of the buttons are NOT removed. My observation is
that every other button is being removed instead.

Is there any reason why I would be getting this behavior? Is there any
reason why the controls.remove command would not remove a specific button?

I suspect more informaiton is needed on this, but what I'm doing is pretty
straight forward, so I have nothing else to post.

Any help is appreciated.

Greg
 
S

Steve Gerrard

Greg said:
I use the following code to remove the buttons on the screen.

For Each btn as Windows.Forms.Button in Me.Controls
controls.remove(btn)
Next

My observation is that every other button is
being removed instead.

Is there any reason why I would be getting this behavior? Is there any
reason why the controls.remove command would not remove a specific
button?

The interator of the For loop (btn) gets lost. If you just have a debug
statement, the contents of the collection doesn't change during the loop. If you
are removing the buttons, though, the content does change, especially if you
remove the control the iterator is currently "on".

The "every other one" effect is because there is no current btn when it gets to
the Next, so the next btn becomes the current btn, and the one after that
becomes the next btn. It is generally true of collections.
 
J

Jack Jackson

I have the following code the dynamically adds a specific number of controls.

for x as integer = 1 to 10
Dim btn as Windows.Forms.Button = New Windows.Forms.Button
btn.Name = "btn" & x
btn.Text = "Test" & x
controls.add(btn)
next x

This results in 10 buttons appearing on the screen. I've excluded the
location info.

Now, in my program the number of buttons varies based on the size of the
form. If the form is decreased in size I will display less buttons. But,
before I update the buttons on the screen, I just remove them all before
refreshing the screen with new buttons.

I use the following code to remove the buttons on the screen.

For Each btn as Windows.Forms.Button in Me.Controls
controls.remove(btn)
Next

In my example, I have 48 buttons displayed on the screen. When the Remove
code above runs it does not delete/remove all of the buttons. If I replace
the controls.Remove command with a debug.print command I can see that every
button is found in the loop. But, when I replace the debug.print and put the
conttols.remove back in all of the buttons are NOT removed. My observation is
that every other button is being removed instead.

Is there any reason why I would be getting this behavior? Is there any
reason why the controls.remove command would not remove a specific button?

I suspect more informaiton is needed on this, but what I'm doing is pretty
straight forward, so I have nothing else to post.

Any help is appreciated.

Greg

Don't change a list while traversing it with an iterator (For Each).
That at a minimum confuses the iterator and at worst gives you an
exception.

You could remove all of the buttons with:
controls.Clear()

But you really should dispose of the buttons so that the Window
handles for the controls get released right away:

For indx As Integer = Controls.Count-1 To 0 Step -1
Dim ctl As Control

ctl = Controls.Item(indx)
Controls.Remove(ctl)
ctl.Dispose()
Next
 
J

Just_a_fan

Conceptually, to avoid getting lost doing this sort of thing (deleting
what you are looping on), do it another way.

Have a While loop which runs while there are controls still existent and
always delete the first one, ONLY, then let the loop cycle and only
delete the first one again. This way, you don't saw off the limb you
are sitting on.

Mike
 

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