Entwickler-Ecke
Sonstiges (.NET) - listBox Index
AlanWake - Mi 18.08.10 20:14
Titel: listBox Index
Hallo C# Forum,
Ich hatte mir vor ein paar Tagen eine listBox1 mit 2 Buttons erstellt gehabt, wenn ich auf den einen Button drücke geht der Index der listBox1 um 1 hoch und bei dem anderen um 1 runter !
Meine Frage wahr gewesen gibt es eine Möglichkeit wenn ich auf den Button drücke, das er automatisch 1 runter/hoch geht aber das immer und immer wieder macht also die Liste runter/hoch läuft ?
Das ist mein Button Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| if (this.listBox1.SelectedIndex == -1 || this.listBox1.SelectedIndex == listBox1.Items.Count - 1)
return;
Object select, next, temp;
select = listBox1.Items[listBox1.SelectedIndex + 1];
next = listBox1.Items[listBox1.SelectedIndex];
temp = select;
select = next;
next = temp;
listBox1.Items[listBox1.SelectedIndex] = select;
listBox1.Items[listBox1.SelectedIndex + 1] = next;
listBox1.SelectedIndex++; |
g Alan
AlanWake - Mi 18.08.10 21:23
Habe es selber herausgefunden !
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| while (HelpButton == true) { if (this.listBox1.SelectedIndex == -1 || this.listBox1.SelectedIndex == listBox1.Items.Count - 1)
return;
Object select, next, temp;
select = listBox1.Items[listBox1.SelectedIndex + 1];
next = listBox1.Items[listBox1.SelectedIndex];
temp = select;
select = next;
next = temp;
listBox1.Items[listBox1.SelectedIndex] = select;
listBox1.Items[listBox1.SelectedIndex + 1] = next;
listBox1.SelectedIndex++; } |
Jetzt habe ich aber das Problem das es nur 1 Sekunde dauert bis die Liste durchgelaufen ist, gibt es eine Möglichkeit die while Schleife zu verlangsamen ?
g Alan
Trashkid2000 - Do 19.08.10 06:30
Hi AlanWake,
Also, habe mal versucht zu verstehen, was der Code denn so macht. Aber zu einem klaren Ergebnis bin ich echt nicht gekommen... im Endeffekt willst Du doch immer nur den SelectedIndex hoch- bzw. runterzählen. Oder? Warum fängst du dann an, an den ListBoxItems Hand anzulegen?
Im Endeffekt reicht doch für Dich aus:
(Beispiel für's runterzählen)
C#-Quelltext
1: 2: 3: 4: 5:
| while (listBox1.SelectedIndex > -1) { listBox1.SelectedIndex--; Thread.Sleep(200); } |
Problem dabei ist, dass solange die Schleife arbeitet, die Form nicht ansprechbar ist. Also müsste das in einem eigenen Thread geschehen.
LG, Marko
Th69 - Do 19.08.10 10:24
Für so etwas benutzt man einen Timer, anstatt einen eigenen Thread (da dieser sowieso mittels Control.Invoke wieder auf die GUI-Elemente zugreifen müßte).
AlanWake - Fr 20.08.10 23:38
@ Trashkid2000 Das mit dem Thread.Sleep hat super funktioniert aber leider stürtz das Programm immer ab mit deiner Methode um immer 1 runter zu gehen !
@ Th69 Ich hatte es schon mal mit einen Timer versucht, nur leider hat es nicht funktioniert.
Kannst du mir einen Beispiel Code geben ?
Th69 - Fr 20.08.10 23:49
Na gut -)
Zieh dir die Timer-Komponente auf deine Form drauf und setze dort dann das Intervall (z.B. auf 200) und doppelklicke es, so daß dann die Tick-Methode erzeugt wird:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| void timer_Tick(object sender, EventArgs e) { if(listBox1.SelectedIndex > -1) { listBox1.SelectedIndex--; } } |
Initial deaktivierst du dann den Timer (Enabled = false).
Und in der Button-Klick-Methode aktivierst du dann den Timer (z.B. "timer.Enabled = true;")
Am besten dann noch einen "Stop"-Button, der den Timer dann wieder deaktiviert.
Für hoch und runter legst du dann entweder noch einen Timer an oder aber du machst in der obigen Timer-Methode einen Abfrage á la "if(hoch) ... else ...".
Wichtig ist, daß du im Timer immer nur genau 1 Aktion ausführst, also dort keine Endlos-Schleife einbaust (damit die GUI weiterhin bedienbar bleibt).
P.S. Noch bzgl. "Absturz" beim Code von Trashkid2000: dies wäre dann beschriebene Schleife, welche die GUI unbedienbar macht (daher hat er ja auch von "eigenem Thread" geschrieben)...
Yogu - Sa 21.08.10 16:23
Th69 hat folgendes geschrieben : |
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| void timer_Tick(object sender, EventArgs e) { if(listBox1.SelectedIndex > -1) { listBox1.SelectedIndex--; } } | |
Man könnte sich den zweiten Timer sparen, wenn man in der Eigenschaft
Tag des Timers entweder eine 1 oder eine -1 speichert - je nachdem, welcher Button gedrückt wurde - und die dann zu
listBox1.SelectedIndex addiert. Natürlich muss dann auch geprüft werden, ob das Ergebnis zu klein oder zu hoch ist.
Th69 hat folgendes geschrieben : |
Und in der Button-Klick-Methode aktivierst du dann den Timer (z.B. "timer.Enabled = true;")
Am besten dann noch einen "Stop"-Button, der den Timer dann wieder deaktiviert. |
Ich habe das so verstanden, dass der Benutzer die Taste gedrückt halten soll, um weiter zu blättern. In diesem Fall wäre das
MouseDown-Ereignise anstatt
Click und das
MouseUp-Ereignis anstatt dem Stopp-Button angebracht.
Als kleinen Zusatz gäbe es noch ein paar Kosmetikdinge, die man einbauen könnte: Zum einen sollte beim Drücken des Buttons sofort um einen Eintrag weitergesprungen werden, nicht erst nach ein paar hundert Millisekunden. Außerdem wäre es sinnvoll, die erste Verzögerung gegenüber den folgenden zu verlängern, damit ein einfacher Klick gut möglich ist. Um den ersten Punkt zu lösen, kannst du im
MouseDown-Ereignis sofort eine Bewegung durchführen. Für den zweiten Satz musst du die
Interval-Eigenschaft in der
MouseDown-Methode auf einen hohen Wert setzen, und im
Tick-Ereignis des Timers auf einen niedrigeren.
AlanWake - Sa 21.08.10 19:03
Das mit dem Timer hat gut geklappt leider wie bei dem aderen, stürtz das Programm ab wenn die Liste bei dem letzten Index angekommen ist !
Das hier ist mein Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| private void button1_Click(object sender, EventArgs e) { timer1.Start(); }
private void timer1_Tick(object sender, EventArgs e) { if (listBox1.SelectedIndex > -1) { listBox1.SelectedIndex++; } } |
Trashkid2000 - Sa 21.08.10 19:52
Also, das mit dem Programmabsturz ist immer gut umschrieben. Hört sich immer so an, als ob sich das Programm ohne eine Meldung verabschiedet.
Aber eigentlich wird doch eine ArgumentOutOfRange-Exception geworfen.
Und das ist auch logisch. Denn der Index wird immer weiter hochgezählt, und die Abbruchbedingung ist, dass der Index >= 0 ist. Das wäre ja für das runterzählen richtig.
Aber für das hochzählen müsste abgefragt werden, ob denn der aktuelle Index < Anzahl der Items -1 ist.
Andernfalls kannst Du denn gleich mal den Timer auf Enabled = false stellen.
LG, Marko
AlanWake - Sa 21.08.10 20:52
Ich habe das mit dem Timer jetzt ausproboiert, ich bleibe lieber bei Thread.Sleep !
Danke für die hilfe :)
Th69 - So 22.08.10 09:59
Hallo AlanWake,
warum machen wir uns eigentlich die Mühe dir etwas zu erklären?
Mit Thread.Sleep im Mainthread blockierst du doch deine GUI!!!
AlanWake - So 22.08.10 15:47
Ihr habt euch nicht umsonst die Mühe gemacht aber das was ich mir vorgestellt habe ist nur mit Theard.Sleep möglich !
Yogu - So 22.08.10 15:56
Was genau hast du dir denn vorgestellt?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!