Kasowania z listy i tablicy - problem

0

Chciałem usunąć zaznaczone elementy z listy oraz odpowiednie dane z tablicy. Napisałem tak:

for (int i = listView.SelectedIndices.Count - 1; i > 0; i--)
{
  Data.Delete((int)listView.Items[listView.SelectedIndices[i]].Tag);
  listView.Items[(int)listView.SelectedIndices[i]].Remove();
}

lecz nie kasuje wszystkich pozycji :-( Jak to powinno być, żeby skasował wszystkie zaznaczone pozycje [glowa]

0

Prawie mam ;]

for (int i = listView.SelectedIndices.Count - 1; i > -1; i--)

Tylko pytanie: jak dam warunek końca pętli

i == 0 

to guzik się dzieje :-/

Identyczną operację wykonuje na liście w Delphi

for I := lvFiles.Items.Count - 1 downto 0 do

i wszystko jest cacy, a tu nie [glowa]

0

Strasznie pod górkę kombinujesz :). Na moje oko, to najprościej będzie:

foreach (ListViewItem item in listView1.Items)
{
	if (item.Selected) item.Remove();
}

Ewentualnie, jeżeli masz przyzwyczajenia z C/C++ i nie lubisz pętli foreach, to taki zapis będzie dla Ciebie czytelniejszy:

for(int i=0; i< listView1.Items.Count; i++)
{
if (listView1.Items[i].Selected) listView1.Items[i].Remove();
}
0

Elegancko działa dla ListView :-) lecz muszę jeszcze z obiektu ArrayList skasować elementy na odpowiednich indeksach :-|

            foreach (ListViewItem Item in listView.SelectedItems)
            {
                Data.Delete((int)Item.Tag);
                Item.Remove();
            }

Z listy

ArrayList Data

masowo można kasować tak jak ze stosu, bo inaczej indeksy nie będą się zgadzały :-( Da rade tym foreach to zrobić [glowa]

0

Foreach'em nie wolno zmieniać zawartości kontenera po którym iterujemy !
Przy liście działa tylko dlatego, że iterujesz po tymczasowej liście SelectedItems (jej zawartośc się nie zmienia), a nie po tej z której elementy usuwasz.

Stary sprawdzony sposób będzie najlepszy:

int offset = 0;
for(int i = 0; i < count; i++)
   if(do_usuniecia(tab[i])) offset++; else tab[i-offset] = tab[i];
skroc_tablice(tab, offset);
0
adf88 napisał(a)

Foreach'em nie wolno zmieniać zawartości kontenera po którym iterujemy !

Eeee... A tak właściwie, to dlaczego? I czy to dotyczy tylko 'kontenerów', czy zwykłych tablic też? Pytam serio, bo nie wiem... W C# dopiero zaczynam, ale zdawało mi się, że używałem prawie identycznej konstrukcji i działało. Choć być może był to zbieg okoliczności.

0

Żeby zrozumieć dlaczego zapoznaj się z interfejsem IEnumerator oraz IEnumerable i przeczytaj co to jest ten foreach. Najprościej mówiąc foreach iteruje po kontenerze iteratorem (o interfejsie IEnumerable). W momencie usuwania elementu z kontenera iterator ten nie jest aktualizowany i przejście do następnego elementu może zakończyć się błędem lub przejściem nie do tego elementu co trzeba. Np w tablicy, jeśli iteratorem byłby porostu indeks, to w momencie kiedy iterator wskazuje np na element 5 i go usuwamy, wtedy na miejsce elementu 5 wskakuje element 6. Następny krok foreach inkrementuje iterator z 5 na 6, bo podczas usuwania nie został on zaktualizowany. A żeby działało poprawnie to powinien wskazywać na element 6 sprzed usunieci 5tki, czyli dalej na 5.

adf88 - IEnumerable ;-)
ups, przekręciłem z rozpędu, już poprawiam. A tak na marginesie to nie wiedziałem, że delegate'a można definiować w ten sposób, genialne :)

0
MyArrayList = MyArrayList.FindAll(new delegate(object x) { (return ((MyClass)x.Pole != 5);  } )

Usunie te elementy, których pole "Pole" ma wartość 5..

adf88 - IEnumerable ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1