Board index » delphi » TCombobox.Items.Delete not working

TCombobox.Items.Delete not working

Hi,

    I have this simple for loop:

           x := TCombobox.Items.Count;
           for i := 0 to x do
                  TCombobox.Items.Delete(i);

To me, I believe that this code should remove all strings from the
combobox, yet it doesn't.  I've stepped through this loop looking at
each string after it's been deleted and it does go through the correct
amount of times, yet it doesn't perform the delete everytime.  Some
strings are left in there and therefore messing up how my program is
supposed to work.  Does anybody know how I might fix this?

Thanks in Advance
Ghost

PS. Adding strings to the combobox is done in the same function but
there is no problem with that.  I traced the problem to this for loop
as not deleting all the strings, therefore giving me undesired
results.  The for loop is done in the OnChange event for a TEdit box
and is the first thing to get done.

 

Re:TCombobox.Items.Delete not working


Look at For L9 = Max DownTo 0 Do

Also TCombobox.Clear

On 19 Jun 2003 07:14:57 -0700, jeremy_gilbe...@hotmail.com (Ghost)
wrote:

Quote
>Hi,

>    I have this simple for loop:

>           x := TCombobox.Items.Count;
>           for i := 0 to x do
>                  TCombobox.Items.Delete(i);

>To me, I believe that this code should remove all strings from the
>combobox, yet it doesn't.  I've stepped through this loop looking at
>each string after it's been deleted and it does go through the correct
>amount of times, yet it doesn't perform the delete everytime.  Some
>strings are left in there and therefore messing up how my program is
>supposed to work.  Does anybody know how I might fix this?

>Thanks in Advance
>Ghost

>PS. Adding strings to the combobox is done in the same function but
>there is no problem with that.  I traced the problem to this for loop
>as not deleting all the strings, therefore giving me undesired
>results.  The for loop is done in the OnChange event for a TEdit box
>and is the first thing to get done.

Re:TCombobox.Items.Delete not working


well think about that.
lets say you have 2 items in the list.
you delete the first one in index 0.
the combox box now only has 1 item remaining.
the for loop moves it's index to 1;
and then you try to remove item #1 which does not exist because you have
forced it down to index 0
 removing 1 item isn't a problem , but removing a block of items is..
 you have 2 choices.
  count backwards.
for x := Count-1 downto 0
 or
simply keep the index delete possition the same and simply use the for
loop as the
recession count.
for example
 for x := 0 to count-1 do Combo.itmes.delete(0); or what ever location you
want to start at.
Quote
Ghost wrote:
> Hi,

>     I have this simple for loop:

>            x := TCombobox.Items.Count;
>            for i := 0 to x do
>                   TCombobox.Items.Delete(i);

> To me, I believe that this code should remove all strings from the
> combobox, yet it doesn't.  I've stepped through this loop looking at
> each string after it's been deleted and it does go through the correct
> amount of times, yet it doesn't perform the delete everytime.  Some
> strings are left in there and therefore messing up how my program is
> supposed to work.  Does anybody know how I might fix this?

> Thanks in Advance
> Ghost

> PS. Adding strings to the combobox is done in the same function but
> there is no problem with that.  I traced the problem to this for loop
> as not deleting all the strings, therefore giving me undesired
> results.  The for loop is done in the OnChange event for a TEdit box
> and is the first thing to get done.

Re:TCombobox.Items.Delete not working


On 19 Jun 2003 07:14:57 -0700, jeremy_gilbe...@hotmail.com (Ghost)
waffled on about something:

Quote
>Hi,

>    I have this simple for loop:

>           x := TCombobox.Items.Count;
>           for i := 0 to x do
>                  TCombobox.Items.Delete(i);

>To me, I believe that this code should remove all strings from the
>combobox, yet it doesn't.  I've stepped through this loop looking at
>each string after it's been deleted and it does go through the correct
>amount of times, yet it doesn't perform the delete everytime.  Some
>strings are left in there and therefore messing up how my program is
>supposed to work.  Does anybody know how I might fix this?

>Thanks in Advance
>Ghost

>PS. Adding strings to the combobox is done in the same function but
>there is no problem with that.  I traced the problem to this for loop
>as not deleting all the strings, therefore giving me undesired
>results.  The for loop is done in the OnChange event for a TEdit box
>and is the first thing to get done.

I'll assume you actually want to do more than just empty the combo, or
I'd just reply combobox.items.clear.

The problem is when you delete item i, it goes, and then everything
else shuffles up to fill the space... So item i+1 moves to i, i+2
moves to i+1 etc etc...
You go round the loop and delete i+1... So you've just missed one.

Eventually you actually run off the end of the list and you'll get an
out of range error because the list no longer contains the count value
you started with.

The best way to deal with it is loop backwards.

for i = combobox.items.count-1 downto 0 do
begin
  combobox.items.delete(i);
end;

Dodgy.
--
MUSHROOMS ARE THE OPIATE OF THE MOOSES

Re:TCombobox.Items.Delete not working


Quote
Dodgy <Do...@earth.planet.universe> wrote in message <news:hnj3fv44cj9i1l2tcohsm279i09vvrsgj9@4ax.com>...
> On 19 Jun 2003 07:14:57 -0700, jeremy_gilbe...@hotmail.com (Ghost)
> waffled on about something:

> >Hi,

> >    I have this simple for loop:

> >           x := TCombobox.Items.Count;
> >           for i := 0 to x do
> >                  TCombobox.Items.Delete(i);

> >To me, I believe that this code should remove all strings from the
> >combobox, yet it doesn't.  I've stepped through this loop looking at
> >each string after it's been deleted and it does go through the correct
> >amount of times, yet it doesn't perform the delete everytime.  Some
> >strings are left in there and therefore messing up how my program is
> >supposed to work.  Does anybody know how I might fix this?

> >Thanks in Advance
> >Ghost

> >PS. Adding strings to the combobox is done in the same function but
> >there is no problem with that.  I traced the problem to this for loop
> >as not deleting all the strings, therefore giving me undesired
> >results.  The for loop is done in the OnChange event for a TEdit box
> >and is the first thing to get done.

> I'll assume you actually want to do more than just empty the combo, or
> I'd just reply combobox.items.clear.

> The problem is when you delete item i, it goes, and then everything
> else shuffles up to fill the space... So item i+1 moves to i, i+2
> moves to i+1 etc etc...
> You go round the loop and delete i+1... So you've just missed one.

> Eventually you actually run off the end of the list and you'll get an
> out of range error because the list no longer contains the count value
> you started with.

> The best way to deal with it is loop backwards.

> for i = combobox.items.count-1 downto 0 do
> begin
>   combobox.items.delete(i);
> end;

> Dodgy.

Thanks for all the help guys, this solved my problem.
Ghost

Re:TCombobox.Items.Delete not working


In article <55f559cc.0306190614.5fdda...@posting.google.com>,

Quote
jeremy_gilbe...@hotmail.com (Ghost) writes:
>    I have this simple for loop:

>           x := TCombobox.Items.Count;
>           for i := 0 to x do
>                  TCombobox.Items.Delete(i);

Others have given you the reason, alternatively use ...

  ComboBox1.Items.Text := '';

BTW what's this "TComboBox" - by convention only type names are prefixed with a
"T", and in any case there is also a TComboBox type. You may well confuse
yourself and Delphi by naming a combobox instance as "TComboBox".

Alan Lloyd
alangll...@aol.com

Re:TCombobox.Items.Delete not working


Quote
AlanGLLoyd wrote in message

<20030619143302.14837.00000...@mb-m03.aol.com>...

Quote
>In article <55f559cc.0306190614.5fdda...@posting.google.com>,
>jeremy_gilbe...@hotmail.com (Ghost) writes:

>>    I have this simple for loop:

>>           x := TCombobox.Items.Count;
>>           for i := 0 to x do
>>                  TCombobox.Items.Delete(i);

>Others have given you the reason, alternatively use ...

>  ComboBox1.Items.Text := '';

>BTW what's this "TComboBox" - by convention only type names are prefixed
with a
>"T", and in any case there is also a TComboBox type. You may well confuse
>yourself and Delphi by naming a combobox instance as "TComboBox".

I also use it to express "this works for any <Type>" (see?).
Other people might write MyComboBox or $COMBOBOX, both of
which I consider ugly.

Groetjes,
Maarten Wiltink

Re:TCombobox.Items.Delete not working


"Maynard Philbrook" <UseThis.jami...@mindspring.com> skrev i melding
news:3EF1CD61.CBD1B49@mindspring.com...

Quote
> well think about that.
> lets say you have 2 items in the list.
> you delete the first one in index 0.
> the combox box now only has 1 item remaining.
> the for loop moves it's index to 1;
> and then you try to remove item #1 which does not exist because you have
> forced it down to index 0
>  removing 1 item isn't a problem , but removing a block of items is..
>  you have 2 choices.
>   count backwards.
> for x := Count-1 downto 0
>  or
> simply keep the index delete possition the same and simply use the for
> loop as the
> recession count.
> for example
>  for x := 0 to count-1 do Combo.itmes.delete(0); or what ever location you
> want to start at.

in this loop, the expression "count-1" is evaluated upon entry, not at every
iteration.

  while Combo.itmes.count > 0 do Combo.items.delete(0);

would be better (or, of course, Combo.Items.Clear...;-)
--
Regards,

Bj?rge S?ther
bjorge@haha_itte.no
-------------------------------------
I'll not spend any money on American Software products
until armed forces are out of Iraq.

Re:TCombobox.Items.Delete not working


Quote
"Bj " wrote:
>> for x := 0 to count-1 do Combo.itmes.delete(0); or what ever location you
>>want to start at.

> in this loop, the expression "count-1" is evaluated upon entry, not at every
> iteration.

That's right. That's by design. Notice that the index passed to Delete
has absolutely nothing to do with the loop variable, though. The loop
could be written like this (assuming no range-check errors) and it would
still clear the whole list.

for x := -Items.Count to -1 do Items.Delete(0);

or

for x := 540 to Items.Count + 539 do Items.Delete(0);

Quote
>   while Combo.itmes.count > 0 do Combo.items.delete(0);

> would be better (or, of course, Combo.Items.Clear...;-)

No, it wouldn't be better. You'd be evaluating Items.Count many times
when you really only need to evaluate it once.

--
Rob

Re:TCombobox.Items.Delete not working


Yes, I was wrong....and you were right. And - it's a good example of how the
simplest code may be confusing when written a little unconventional...;-)

--
Regards,

Bj?rge S?ther
bjorge@haha_itte.no
-------------------------------------
I'll not spend any money on American Software products
until armed forces are out of Iraq.
"Rob Kennedy" <rkenn...@example.com> skrev i melding
news:vf4lm2n6jsgu37@corp.supernews.com...

Quote
> "Bj????????????????????????????????????" wrote:
> >> for x := 0 to count-1 do Combo.itmes.delete(0); or what ever location
you
> >>want to start at.

> > in this loop, the expression "count-1" is evaluated upon entry, not at
every
> > iteration.

> That's right. That's by design. Notice that the index passed to Delete
> has absolutely nothing to do with the loop variable, though. The loop
> could be written like this (assuming no range-check errors) and it would
> still clear the whole list.

> for x := -Items.Count to -1 do Items.Delete(0);

> or

> for x := 540 to Items.Count + 539 do Items.Delete(0);

> >   while Combo.itmes.count > 0 do Combo.items.delete(0);

> > would be better (or, of course, Combo.Items.Clear...;-)

> No, it wouldn't be better. You'd be evaluating Items.Count many times
> when you really only need to evaluate it once.

> --
> Rob

Re:TCombobox.Items.Delete not working


In article <3ef21d41$0$49100$e4fe5...@news.xs4all.nl>, "Maarten Wiltink"

Quote
<maar...@kittensandcats.net> writes:
>I also use it to express "this works for any <Type>" (see?).
>Other people might write MyComboBox or $COMBOBOX, both of
>which I consider ugly.

So do I but only in descriptive text or pseudo-code, not in actual code. I
remember being very confused by those who used the type name in actual code
examples in my early days.

I agree that MyComboBox is a bit ugly (and $COMBOBOX is not only ugly but also
confusing), but it is _very_ clear. So how about AComboBox ?

Alan Lloyd
alangll...@aol.com

Re:TCombobox.Items.Delete not working


"Maarten Wiltink" <maar...@kittensandcats.net> skrev i melding
news:3ef21d41$0$49100$e4fe514c@news.xs4all.nl...

Quote
> AlanGLLoyd wrote in message
> <20030619143302.14837.00000...@mb-m03.aol.com>...
> >In article <55f559cc.0306190614.5fdda...@posting.google.com>,
> >jeremy_gilbe...@hotmail.com (Ghost) writes:

> >>    I have this simple for loop:

> >>           x := TCombobox.Items.Count;
> >>           for i := 0 to x do
> >>                  TCombobox.Items.Delete(i);

> >Others have given you the reason, alternatively use ...

> >  ComboBox1.Items.Text := '';

> >BTW what's this "TComboBox" - by convention only type names are prefixed
> with a
> >"T", and in any case there is also a TComboBox type. You may well confuse
> >yourself and Delphi by naming a combobox instance as "TComboBox".

> I also use it to express "this works for any <Type>" (see?).

Why do you need to use a 'T' then ?

general:
procedure ClearObjects(Strings: TStrings);

specific:
procedure ClearFields(Fields: TStrings);

...no doubt that the parameter 'Strings: TStrings' is the generalized one
here ?

Quote
> Other people might write MyComboBox or $COMBOBOX, both of
> which I consider ugly.

I believe I use 'AComboBox' (especially for methods, to distinguish from
fields), 'ComboBox' or 'Combo', or even 'Cmb' when I'm in a hurry or just
lazy.
--
Regards,

Bj?rge S?ther
bjorge@haha_itte.no
-------------------------------------
I'll not spend any money on American Software products
until armed forces are out of Iraq.

Re:TCombobox.Items.Delete not working


Quote
alangll...@aol.com (AlanGLLoyd) wrote in message <news:20030620014356.25052.00000691@mb-m11.aol.com>...
> In article <3ef21d41$0$49100$e4fe5...@news.xs4all.nl>, "Maarten Wiltink"
> <maar...@kittensandcats.net> writes:

> >I also use it to express "this works for any <Type>" (see?).
> >Other people might write MyComboBox or $COMBOBOX, both of
> >which I consider ugly.

> So do I but only in descriptive text or pseudo-code, not in actual code. I
> remember being very confused by those who used the type name in actual code
> examples in my early days.

> I agree that MyComboBox is a bit ugly (and $COMBOBOX is not only ugly but also
> confusing), but it is _very_ clear. So how about AComboBox ?

> Alan Lloyd
> alangll...@aol.com

I give my components suitable names so that I can distinguish them
when I am programming.  But when posting here, it's simpler to just
state that I am using a TComboBox component rather than cb_Student.
Most people would know what I meant, but there still might be some who
didn't.

Ghost

Re:TCombobox.Items.Delete not working


Quote
"Ghost" <jeremy_gilbe...@hotmail.com> wrote in message

news:55f559cc.0306190614.5fdda273@posting.google.com...

Quote
> Hi,

>     I have this simple for loop:

>            x := TCombobox.Items.Count;
>            for i := 0 to x do
>                   TCombobox.Items.Delete(i);

There is not need to use debug to see what is wrong with this code. In fact
doing so is likely going to extend the time it takes to solve the problems.
I use debug as a last, not first resort. Its the way was trained and, I
believe, it makes be a better problem solver. Using debug first, IMO, often
leads to the problem of not seeing the forest for all the trees in the way.

Others have pointed out the errors, but I'd like to summarize them.

The first set of problems that X is set to the number of items in the list
before any deletion. Since the list is indexed from zero this means that a)
the loop will always cause an invalid index when index = X, regardless of
any deletion; and b) each deletion will cause an additional invalid index
since Items.Count will be decremented for each deletion, i.e. the distance
between (Items.Count - 1) and X will increase by one. Finally, and the
problem that you probably noticed first, since (as documented) deleting the
first item (index zero) from the list immediately decrements the index of
all following items, not all items will be remove from the list.

Each of us has probably written similar code and learned these lessons the
hard way. Always verify loop bounds first. Always remember when working with
dynamic data structures that they are in fact dynamic and additions and
deletions change things. When increasing, increment. When decreasing,
decrement. Always remember that the VCL rarely requires that one write more
than one or two lines of code. (E.G. ComboBox.Clear.)

Other Threads