• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

[C#] Mehrfachauswahl und Löschen funktioniert nicht richtig

Cyperfriend

Der ohne Avatar

Registriert
14 Juli 2013
Beiträge
1.123
Ich arbeite immer noch fleißig an den Übungen und versuchte einmal mehr eine zu erweitern. Eigentlich wird in dem Buch nur gezeigt, wie ich mir die Mehrfachauswahl in einem Listenfeld als Text anzeigen lassen kann. Da aber im vorangegangenem Beispiel bereits ein Programm geschrieben wurde mit dem man (einzelne) Einträge löschen kann wollte ich direkt dieses Programm erweitern und mehrere Einträge auf einmal löschen (anstatt die mir nur in einem Text anzeigen zu lassen)

Die Eigenschaft "SelectionMode" ist auf "MultiSimple" gestellt ("MultiExtended" führt zum gleichen Ergebnis)
Mit dem folgenden Code wird bei einer einfachen Auswahl immer der oberste Eintrag gelöscht und bei einer mehrfachen Auswahl irgendwie je nach Anzahl der ausgewählten Elemente zwei bis drei Einträge. Habs aber nicht ganz kapiert. Jedenfalls funktioniert es so halt nicht. Hier mal der Code. Wäre toll, wenn mir jemand sagt wo der Fehler liegt.

[src=csharp]
private void cmdElementLoeschen_Click(object sender, EventArgs e)
{
int x = lstSpeisen.SelectedIndex;
if (x != -1)
{
for (x = 0; x < lstSpeisen.SelectedItems.Count; x++)
{
lstSpeisen.Items.RemoveAt(x);
}
}

}[/src]


Edit: Falls jemand das Tool nachschreiben möchte, hier der Code um das Listenfeld schnell zu füllen:
[src=csharp]
private void Form1_Load(object sender, EventArgs e)
{
lstSpeisen.Items.Add("Spaghetti");
lstSpeisen.Items.Add("Grüne Nudeln");
lstSpeisen.Items.Add("Tortellini");
lstSpeisen.Items.Add("Pizza");
lstSpeisen.Items.Add("Lasagne");
}[/src]
 

evillive

EXIL

Registriert
24 Juli 2013
Beiträge
930
wenn du eine Menge { a, b, c, d, e } hast

dann hat c den Index 2 und d den Index 3

löscht du nun c, dann hat nun d den Index 2. Da liegt die Problematik. In dem Beispiel mit der Ausgabe verändert sich der Index von den Elementen nicht
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
Du mußt die 2 Listen trennen, die Liste mit allen Elementen und die Liste mit den selektierten.

Du löschte jetzt momentan aus der Liste so viele Elemente, wie Du gewählt hast. Also egal welche 3 Du wählst, immer die ersten 3.

Beim Löschen aus Listen muß man auch bedenken, daß man durch Wegnahme eines Elementes den Index zerstört.

Eine Möglichkeit wäre jetzt hier von Hinten zu löschen.

dies sollte funktionieren:

[src=csharp] for (x = lstSpeisen.SelectedItems.Count-1; x >=0 ; x--)
{
lstSpeisen.Items.Remove(lstSpeisen.SelectedItems[x]);
}[/src]
 

electric.larry

\''; DROP TABLE user; --
Teammitglied

Registriert
13 Dez. 2014
Beiträge
4.549
Ort
Raum 43
Schau dir nocheinmal genau an, was deine Schleife hier macht.

Du verwendest RemoveAt um einen Listeneintrag an einer bestimmten Stelle in deiner Listbox zu entfernen. Wenn du zum Beispiel deine Tortellini loeschen moechtest, wuerde der Aufruf lauten:

[src=csharp]lstSpeisen.Items.RemoveAt(2);[/src]

Willst du die Spaghetti loeschen, waere das:

[src=csharp]lstSpeisen.Items.RemoveAt(0);[/src]

So weit alles klar? Schauen wir uns deine Schleife an. Um die Anzahl der Durchlaeufe zu begrenzen verwendest du

[src=csharp]lstSpeisen.SelectedItems.Count[/src]

Was liefert diese Funktion genau zurueck? Sie gibt die Anzahl der ausgewaehlten Listbox Items. Wenn du 3 Eintraege in deiner Listbox ausgewaehlt hast, liefert sie 3. Hast du einen Item selektiert, bekommst du 1 und wenn nichts ausgewaehlt ist, liefert sie folglich 0.

Schauen wir also auf deine gesamte Schleife, was tut sie wenn wir 3 beliebige Eintraege ausgewaehlt haben und den Button klicken?

[src=csharp]for (x = 0; x < lstSpeisen.SelectedItems.Count; x++)[/src]

lstSpeisen.SelectedItems.Count hat den Wert 3. Die Schleife wird so lange wiederholt, bis x maximal 2 ist.

Denken wir uns jetzt den Ablauf in der Schleife Schritt fuer Schritt durch.

Am Beginn haben wir Spaghetti auf Platz 0 in der Listbox. Gefolgt von "Grune Nudeln" auf Platz 1 und "Tortellini" auf Platz 2 und die Pizza auf Stelle 3.

0 - Spaghetti
1 - Gruene Nudeln
2 - Tortellini
3 - Pizza
4 - Lasagne

Im ersten Durchlauf deiner Schleife ist X = 0. Dadurch wird der erste Eintrag in der Listbox, Spaghetti, geloescht. Alle weiteren Eintraege rutschen dadurch in deiner Liste nach oben, wodurch "Gruene Nudeln" jetzt auf Platz 0 sind. "Tortellini" rueckt vor auf Platz 1 und die Pizza ist auf Platz 2. Unsere Liste sieht also so aus:

0 - Gruene Nudeln
1 - Tortellini
2 - Pizza
3 - Lasagne

Jetzt kommt der zweite Durchlauf deiner Schleife. x hat dann den Wert 1 und RemoveAt loescht also den Listbox Eintrag auf Stelle 1, das sind die "Tortellini". Der Item auf Platz 0, Gruene Nudeln, bleibt davon unberuehrt. Die Tortellini sind weg und die Pizza rutscht weiter nach vorne auf Platz 1.
Nach den beiden vorherigen Schleifendurchlaeufen sieht unsere Liste in etwa so aus:

0 - Gruene Nudeln
1 - Pizza
2- Lasagne

Im naechsten und letzten Loop hat x den Wert 2 und es wird die Lasagne geloescht. Uebrig bleiben die Gruenen Nudeln und die Pizza.

Du hast also 2 Probleme auf die du achten musst:

Nummer 1:

Werden Listeneintraege entfernt, dann ruecken die nachfolgenden Eintraege vor und Ihr jeweiliger Index veraendert sich. In unserem Beispiel hatte die Pizza z. B. am Beginn unserer Schleifendurchlaeufe den Index 3 und am Ende den Index 1. Das bedeutet, dass die Indizes, die du dir am Beginn der Loesch-Schleife holst, nach dem loeschen eines Eintrags nicht mehr gueltig sind.
Die Loesung ist ganz einfach, du entfernst die Eintraege in umgekehrter Reihenfolge, also vom hoechsten bis zum niedrigsten Eintrag. Dadurch bleiben die urspruenglichen Indizes erhalten.

Nummer 2:

Du holst dir am Beginn deiner Funktion den ersten selektierten Listbox Eintrag. Dann pruefst du zwar, ob es ueberhaupt eine Auswahl gibt (!= -1) aber danach verwendest du den Index nicht. Du sagst nur, dass x zwischen 0 und 2 sein darf und loescht dann die Items mit diesen Indizes (0, 1, 2) wie oben beschrieben.

[src=csharp]int x = lstSpeisen.SelectedIndex;[/src]

Ueberleg dir, welcher Wert in x stehen wuerde, wenn jemand die Spaghetti auswaehlt; es waere 0. Waehlt jemand die Pizza, bevor er auf den Delete Button klickt, dann haette x den Wert 3.

Was du eigentlich moechtest ist eine Liste der Indizes aller ausgewaehlten Listbox Eintraege:

[src=csharp]lstSpeisen.SelectedIndices[/src]

Danach loopst du von hinten nach vorne durch diese Index Liste und loescht die Eintraege mit dem jeweiligen Index und nicht mit dem Schleifen-Zaehler der in x gespeichert ist.

Schau dir einmal dieses Beispiel auf Stackoverflow an. Hab hier leider keinen C# Interpreter installiert um den Code zu testen, aber fuer dich sollte in etwa soetwas funktionieren:

[src=csharp]private void cmdElementLoeschen_Click(object sender, EventArgs e)
{
//x wird von oben nach unten durchgezaehlt
for(int x = lstSpeisen.SelectedIndices.Count - 1; x>= 0; x--)
{
//idx bekommt den Wert, der an
//der Stelle x in unserer Index Liste steht.
int idx = lstSpeisen.SelectedIndices[x];
//der Eintrag mit dem Index wird aus der Liste geloescht.
lstSpeisen.Items.RemoveAt(idx);
}
} [/src]

Ist dir klar warum SelectedIndices.Count - 1 verwendet wird? Bei drei ausgewaehlten Eintraegen wuerde Count die Zahl 3 zurueck liefern. Bei der Nummerierung unserer Indizes wird aber bei 0 zu zaehlen begonnen. Das heisst, der 3. Listeneintrag haette den Index 2, der erste Eintraeg liegt bei 0.

Hoffe das ist einigermassen verstaendlich. Ist gar nicht einfach zu erklaeren, wenn man betriebsblind ist.

<3
 

Cyperfriend

Der ohne Avatar

Registriert
14 Juli 2013
Beiträge
1.123
  • Thread Starter Thread Starter
  • #5
Danke für die ausführliche Erklärung. Das der Index mit Null beginnt wusste ich schon, aber dass der Index entsprechend immer eins nach vorne rutscht und wie man das behandelt nicht. Das hätte die in dem Buch aber ruhig mal erklären können, weil da steckt ja schon etwas mehr dahinter als nur ein Einträge zu löschen und auch mehr als sich alle markierten Einträge in einem Lael anzeigen zu lassen.

Danke euch jedenfalls
 
Oben