Autor Beitrag
AlanWake
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75
Erhaltene Danke: 2



BeitragVerfasst: Mi 18.08.10 20:14 
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:

ausblenden 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


Zuletzt bearbeitet von AlanWake am Mi 18.08.10 21:24, insgesamt 1-mal bearbeitet
AlanWake Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75
Erhaltene Danke: 2



BeitragVerfasst: Mi 18.08.10 21:23 
Habe es selber herausgefunden !

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: 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)
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75
Erhaltene Danke: 2



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Sa 21.08.10 16:23 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden 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.

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75
Erhaltene Danke: 2



BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75
Erhaltene Danke: 2



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75
Erhaltene Danke: 2



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 22.08.10 15:56 
Was genau hast du dir denn vorgestellt?