Serious discussion about removing dynamically controls

  • Thread starter Thread starter Cor
  • Start date Start date
C

Cor

Hi,
I start a new thread about a discussion from yesterday (or for some of us
this morning). It was a not so nice discussion about dynamically removing
controls from a panel or what ever.
It started by an example from me, that was far from complete and with typing
errors, but basically it had the meaning to show that removing controls
reversible was the nicest method.

This was a lets say conclusion (but what is that in a newsgroup) in a
discussion some weeks ago in this newsgroup. The method was contributed by
Armin. I found it brilliant and since that time I call this the method
Armin.

Jack did totally disagree with this method and did after a while contribute
some code.

Therefore I send both code's to this newsgroup in this new thread. I think
it is good to talk professionally about it. So it is not the code Cor, Nick,
Armin or Jack. Just the method "reverse For next loop", against the "While
end while loop" for removing controls dynamically.

I don't want to start with my + of - points about the methods, maybe I will
give that, but I hope that it will come automatically in this newsgroup

The code that Jack has given some contribution for me, because I did not
know "removeAT" exist. But I always do the things that I do plus in the same
way minus. So I doubt if I will use it, but for the example I did use
"removeAT" (I think it is nicer). Please don't start a discussion about
that. The question is the "While end while" against reversal "For next".

"While end While"
Dim idx As Integer
idx = 0
While idx < Me.Panel1.Controls.Count ' while in bounds
If TypeOf Me.Panel1.Controls.Item(idx) Is Label Then
Me.Panel1.Controls.RemoveAt(idx)
Else
idx = idx + 1 ' otherwise advance to next control
End If
End While
-----------------
"For index Next reversal"
Dim idx As Integer
For idx = Me.Panel1.Controls.Count - 1 To 0 Step -1
If TypeOf Me.Panel1.Controls.Item(idx) Is Label Then
Me.Panel1.Controls.RemoveAt(idx)
End If
Next
I hope this contribute something
Cor
 
I favour the reversal code which I tend to use a lot because it's cleaner
and generally saves you getting into problems.

--
Regards - One Handed Man

Author : Fish .NET & Keep .NET
=========================================
This posting is provided "AS IS" with no warranties,
and confers no rights.
 
ACK (that's me pretending to be Herfried ... I wish)

The only thing I would probably change is

Do While ... Loop

instead of what is essentially a While ... Wend loop.

Charles
 
Time for my 2 pen'orth.

The first thing I need to say is that there is no right or wrong way. What
ever achieves your objective and suits your development style is right for
you.

That said, some ways of doing things tend to be better that other ways in
terms of performance, resource usage etc, but, with some of the advanced
specification of hardware these days, a few milliseconds here and there or a
few KB of menory here or there may not be your biggest concern.

The way I tend to work is to to use the power of the tools as far as I can.

Taking your first example, the problem can be demonstrated thus:

Me.Panel1.Controls
Item 0 = Label1 As Label
Item 1 = Label2 As Label
Item 2 = Label3 As Label

The first thing that is happening is that you are manually maintaing an
index counter. This is a probably performance matter compared to a loop
control variable.

On the first iteration of the loop, idx=0, Me.Panel1.Controls.Count=3 and
TypeOf Me.Panel1.Controls.Item(idx) Is Label equates to True (Label1), so
the first item is removed and the collection now comprises:

Me.Panel1.Controls
Item 0 = Label2 As Label
Item 1 = Label3 As Label

On the second iteration of the loop, idx=0, Me.Panel1.Controls.Count=2 and
TypeOf Me.Panel1.Controls.Item(idx) Is Label equates to True (Label2), so
the first item is removed and the collection now comprises:

Me.Panel1.Controls
Item 0 = Label3 As Label

On the third iteration of the loop, idx=0, Me.Panel1.Controls.Count=1 and
TypeOf Me.Panel1.Controls.Item(idx) Is Label equates to True (Label2), so
the first item is removed and the collection now comprises:

Me.Panel1.Controls

On the forth iteration of the loop, idx=0, Me.Panel1.Controls.Count=0 and so
the iteration is not executed.

Notice that idx has not been modified so the code that manually maintains
the index counter is redundant. If one if the controls wasn't a Label then
idx would have been modified but the code still had to execute the idx = idx
+ 1. (This could simplified to idx += 1).

Taking the second example, there is no manually maintained index counter -
instead, the indexing is controlled by the loop control variable. Because
the collection is being walked backwards there is no need for the idx = idx
+ 1 and, in my view the process is cleaner and 'should be' more efficient.
It could still be simplified thus:

For idx as Integer = Me.Panel1.Controls.Count - 1 To 0 Step -1
If TypeOf Me.Panel1.Controls.Item(idx) Is Label Then
Me.Panel1.Controls.RemoveAt(idx)
Next

It might be interesting, for someone who is so inclined, to compare the
resulting IL code for the 2 methodologies and see if one is more efficient
than the other or if they produce the same IL code.

Please excuse any typos or trivial coding errors.
 
Yes, there will probably be tiny performance differences between the two,
and when dealing with a huge collection, it might be worth looking at.

I personally prefer to see the
Dim idx as Integer = 0 before the loop, it makes it stand out more

and more inportantly.

When you traverse forward through a collection as in scenario one, its easy
to miss out that conditional increment which has bitten me a couple of times
in the past.

--
Regards - One Handed Man

Author : Fish .NET & Keep .NET
=========================================
This posting is provided "AS IS" with no warranties,
and confers no rights.
 
Sorry, I meant

Dim idx as Integer 'before the loop, it makes it stand out more

not . .
Dim idx as Integer = 0 before the loop, it makes it stand out more

--
Regards - One Handed Man

Author : Fish .NET & Keep .NET
=========================================
This posting is provided "AS IS" with no warranties,
and confers no rights.
 
Hi Cor,

http://members.lycos.co.uk/nickpatemanpwp/mynews.htm

I uploaded a quick test of all 3 methods onto my web site, read the top item
on my news page for the download link. It's a tiny file and the tests just
go to show that there is practically nothing in it what so ever.

The test works by adding a user defined number of controls to a panel
(currently @ 10,000), these controls are randomly chosen to be either a
button or a label. The 3 routines then test removing only the label
controls and give a result in (ms), on my computer the results were,

While method = 9937ms
For method (reverese removal) = 9984
For method (my crappy forward removal method) = 9781

Nothing in it what so ever, so it's just a matter of personal preference and
ease of typing isn't it?

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
Hi Nick,
Thanks,
As I promished I give no comments now except.
I measured while 15.453, for, 15.390, cr 15.281
But those slight differences say nothing because it is not a total clean
Computer (there are interupts).
Cor
 
As I promished I give no comments now except.
I measured while 15.453, for, 15.390, cr 15.281
But those slight differences say nothing because it is not a total clean
Computer (there are interupts).
Cor

Hi Cor,

Agreed, the test isn't "clean" as such, but is a test ever clean on a
system with Windows running? It just goes to show how little is in it,
other than programming preference :-)

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
What the *&^% is this all about, a few milliseconds.


I agree with Nak, its down to personal preference

--
Regards - One Handed Man

Author : Fish .NET & Keep .NET
=========================================
This posting is provided "AS IS" with no warranties,
and confers no rights.
 
Hi Stephanie,

Unfortunately, for me with v2002,
For I As Integer = ...
gives a syntax error. Glad it's been added to v2003.


I agree that:

For idx as Integer = Me.Panel1.Controls.Count - 1 To 0 Step -1
If TypeOf Me.Panel1.Controls.Item(idx) Is Label Then
Me.Panel1.Controls.RemoveAt(idx)
Next

is shorter, but to me it <looks> more complicated than with the If spread
out to three lines.

Regards,
Fergus
 
Hi Cor,

I prefer the For loop because it is simpler and shorter on the page.

Simpler for someone trying to understand it:

Correctness
With the For loop you need to ensure that it does
the correct thing in the If.

With the While you have to ensure that it does the
correct thing on both branches of the If.

Progression
The For loop <always>
decrements which makes it straghtforward.

You have to realise that it doesn't always increment,
and be happy that that makes sense.

Imagery
The imagery with the For loop is of going backwards
down a list saying either "You're ok" or "You - out" and
the line shuffling down to close the gap.

The imagery with the While is of going intermittently
forwards up a list saying either "You - stay" and moving
past, or "You - out. Next!" and the line shuffling up to
meet you.

As with the performance issue, the difference is marginal. :-)

For me the overriding consideration is that it takes fewer lines.Lines on the screen, to me, is one hell of a valuable
commodity.

Regards,
Fergus
 
Charles Law said:
ACK (that's me pretending to be Herfried ... I wish)

The only thing I would probably change is

Do While ... Loop

instead of what is essentially a While ... Wend loop.

A 'While...End While' loop.

;-)
 
I didn't mistype it, but hasn't Wend only just been finally banished from
the language? Or did I just dream it!

Charles
[How do I do raised eyebrows, quizzical look? ):-[] maybe? If I have just
indicated something rude or offensive with my attempt, please ignore]
 
Herfried,
I asume this is not your contribution after all you did write last night.
I expect that Tom, Jeremy and Jay B do that for us when it is for us night
(Or is Tom too Europe?).
I think, this is more important than 6 man(3 MVP) who give answers how to
add a preceding zero to a string.
(Sorry but I had to laugh when I saw that)

After doing this the people active in this newsgroup can give an uniform
answer and we have again less so long useless threads anymore.

The only one who I can imaging who gives not comments is Armin, his idea it
obvious.
I and I think others too are curious to the ideas of you and the other
MVP's.

Cor
 
Charles,
I thought that too, but because of the discussion last night I did not want
to contribute that, lets do if the
while end loop is the same as the do while loop.
OK?
Cor
 
Charles
The reversal is the for index and not the Do While
I do not understand you.
when you say
 
Hi Nick
The test is very good to make the discussion beter I think Nick

I try to give no comments, makes evaluating much easier.

I keep doing it on my own way and you too.
But it is good for thinking it over.
Cor
 
Charles Law said:
I didn't mistype it, but hasn't Wend only just been finally
banished from the language? Or did I just dream it!

'Wend' doesn't exist any more.
 
Back
Top