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);
}
}
3 Antworten
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.
das bring nichts; die progressbar wird immernoch auf der hälfte zurückgesetzt
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.
ja ich hatte auch schon drin: if (progressBar1.Value == progressBar1.Maximum)
oder so hat aber auch nicht funktioniert.
ich vermute die animation ist einfach langsamer als der prozess
weil je langsamer der timer desto weiter kommt der balken
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 {...
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);
}
}
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.
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.
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.
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);
}
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.
hä?
so oder was