Frage von Maassmaenchen, 72

C# Progress bar füllt sich nicht komplett aus?

Hallo ich möchte ein programm machen das eine ProgressBar füllen soll und dann ein dialog ausgeben soll. Nur leider wird der Dialog schon ausgegeben bevor die ProgressBar voll ist.

   private void timer1_Tick(object sender, EventArgs e)
    {
        progressBar1.Increment(1);
        if (progressBar1.Value == 100)
        {
            timer1.Stop();
            progressBar1.Value = 0;
            Random r = new Random();
            string randomstring;
            List<string> words = new List<string>();
            words.Add("Wer mit einem Känguru befreundet ist hat warscheinlich auch eine Giraffe als Nacbarn. Oder war`s ein Pinguin? äh moment ... Wie ging des noch ma? ich kann mir diese Sprüche immer so schlecht merken     -Oscar Wilde-");
            words.Add("So ist das in der Welt. Der eine hat den Beutel der andere hat das Geld ");
            words.Add("WAS BISHER GESCHAH:                  NICHTS");
            randomstring = words[r.Next(0, 3)].ToString();
            MessageBox.Show(randomstring);
            
        }
        
    }
Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von Mikkey, 51

Es wäre sinnvoller, wenn Du beim Erreichen der 100 einen weiteren Tick abwartest, damit das System die Gelegenheit erhält, den Fortschrittbalken komplett zu zeichnen.

==> "increment" mit "else" hinter die Messagebox-Anzeige.

Kommentar von Maassmaenchen ,

hä?


so oder was


else
{
progressBar1.Increment(1);
}
Kommentar von Maassmaenchen ,

das bring nichts; die progressbar wird immernoch auf der hälfte zurückgesetzt

Kommentar von Mikkey ,

Hat denn der Progressbar auch 100 als "Maximum"?

Ansonsten als Test mal einen Label mit dem Value belegen, damit man sieht, wie sich das verhält.

Ach ja...

Es ist generell (in jeder Sprache) ungünstig, die Werte von Steuerelementen für die Programmsteuerung zu verwenden, besser ist es, einen eigenen Zähler zu definieren, aus dem man jeweils den Wert des Steuerelements setzt.

Kommentar von Maassmaenchen ,

ja ich hatte auch schon drin: if (progressBar1.Value == progressBar1.Maximum)

oder so hat aber auch nicht funktioniert.

Kommentar von Maassmaenchen ,

ich vermute die animation ist einfach langsamer als der prozess


weil je langsamer der timer desto weiter kommt der balken

Kommentar von Mikkey ,

Nein, das kann nicht sein, so langsam ist das Rendern nicht, dass der Balken auf der Hälfte stehen bleiben würde.

Hast Du das mit dem Label ausprobiert? Separaten Zähler

if (zaehler1 < maxValue) {
progressBar1.Value = ++zaehler;
label1.Text = zaehler.toString();
} else {...
Kommentar von CrystalixXx ,

Aber genau so ist es ab Windows Vista.

Kommentar von Mikkey ,

Natürlich ist es nicht so.

Ich habe diesen Code ausprobiert, er läuft genauso, wie man sich das vorstellt, abgesehen davon, dass die Box etwas vor dem vollständigen Balken kommt:

void Timer1Tick(object sender, EventArgs e)

{
if (progressBar1.Value < progressBar1.Maximum)
progressBar1.Value++;
else
{
timer1.Stop();
MessageBox.Show("Fertig", "Fortschritt", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, 0);
}
}
Kommentar von CrystalixXx ,

Setz den Timer auf ein Interval von 20 ms und du erkennst bei aktiviertem Aero-Design ab Windows Vista einen zeitlichen Versatz. Da lassen sich auch viele Beiträge im Internet dazu finden.

Kommentar von Mikkey ,

In meiner Umgebung kann ich Aero nicht aktivieren, abgesehen davon ist es abgekündigt.

Der Code läuft einwandfrei, man möge dem nicht die Schuld an Bugs aus einem missgestalteten Framework geben.

Kommentar von CrystalixXx ,

Niemand gibt dem Code dafür die Schuld. Ich denke auch nicht, dass das .NET Framework verantwortlich ist. Denn das nutzt auch nur die durch Windows zur Verfügung gestellten Technologien.

Der Code ist auch einwandfrei, nur die Darstellung nicht. Auch wenn sich das durch den von mir erwähnten Code umgehen lässt...

PS: Ich konnte das Fehlverhalten auf Windows 7 und Windows 10 reproduzieren und lies sich durch den Umweg beheben.

Antwort
von Sivsiv, 32

Vermutlich musst du noch einen Window-Update abwarten. Bin mir nicht ganz sicher ob das in .Net so geht, aber ein Thread.Sleep(100) könnte schon helfen nach dem timer1.stop(); 

Warum setzt du den ProgressBar1.Value wieder auf 0? Du musst dir mal überlegen wie schnell das alles abläuft. Zwischen dem Increment  und dem MessageBox.Show vergehen ein paar µs. Selbst wenn die Anzeige aktualisiert würde würde das nichtmal an deinem Bildschirm ankommen.

Kommentar von Maassmaenchen ,

thread.sleep(100) kennt c# aber nicht

Kommentar von Sivsiv ,

Da hast du recht. Es muss heissen:

Thread.Sleep(100);

Aus 

using System.Threading;
Antwort
von CrystalixXx, 21

Du hast mit deiner Vermutung der "langsamen Animation" recht.

Seit Windows Vista ist das Redesign der Progressbar für ein solches Verhalten verantwortlich. Wird der Wert erhöht, dann wird durch Windows eine Animation ausgelöst, die diese Änderung progressiv anzeigt. Je schneller der Wert erhöht wird, desto mehr scheint die Animation hinterher zu hängen.

Eine Möglichkeit diese Animation zu umgehen wäre es beispielsweise den Wert nach dem Erhöhen wieder zu verringern. Zum Beispiel so:

if (progressBar1.Value == progressBar1.Maximum - 1)
{
progressBar1.Increment(1);
}
else
{
progressBar1.Increment(2);
progressBar1.Increment(-1);
}

Keine passende Antwort gefunden?

Fragen Sie die Community