2017-01-12 6 views
-2

In C# ich versuche, ein kleines Spieltyp-Programm zu erstellen und eine Ladeleiste zu erstellen, die die Fortschrittsleiste verwendet und der Text ein Label verwendet, z
C# Etikettentext wird nicht aktualisiert, während der Fortschrittsbalkenwert

private void StartLoading_Click(object sender, EventArgs e) 
    { 
     MainProgressBar.Maximum = 25; 
     int P = 0; 
     while (P < 25) 
     { 
      // Delay 
      System.Threading.Thread.Sleep(130); 
      // Increase Progress 
      P++; 
      // Set Progress Bar Value 
      MainProgressBar.Value = P; 
      // Set Text Above Progress Bar 
      LoadingText.Text = P + "/25"; 
     } 
    } 

Ps: ein Beispiel ist, herer 25 und ich mag der Beschriftungstext, während die Bar aktualisieren - 1. Ich nicht etwas Huge Code will, ich will es wie dies ist für Sie diesen Schnipsel

+0

Versuchen Sie zu suchen, blockieren Sie nicht den UI-Thread, verwenden Sie einen Hintergrundarbeiter. Ja, das ist "riesiger Code", aber es ist notwendig. – CodeCaster

+0

Wenn Sie Ihre Steuerelemente im GUI-Thread aktualisieren, werden die meisten Steuerelemente keine Nachrichten verarbeiten (weil sie die Nachrichten erst erhalten, nachdem die Ausführung beendet wurde). Sie sollten einen Arbeitsthread verwenden. Die zweite Methode (Verarbeitung von Nachrichten) wird nicht empfohlen. Fortschrittsbalken hat ein anderes Verarbeitungssystem, daher funktioniert es wie erwartet, aber es ist meistens eine Ausnahme in grafischen Steuerelementen. – Julo

+0

Nehmen Sie in Ihrem Ansichtsmodell zwei Eigenschaften vor, eine für den Maximalwert und eine für den aktuellen Wert, und binden Sie dann an beide Werte in Ihrer Ansicht. – LordWilmore

Antwort

1

Stand der Technik einfach sein:

private void StartLoading_Click(object sender, EventArgs e) 
    { 
     const int max = 25; 
     var progressHandler = new Progress<int>(value=>{ 
      LoadingText.Text = value + "/" + max; 
      MainProgressBar.Value = value; 
     }); 

     var progress = progressHandler as IProgress<int>; 
     await Task.Run(() => 
     { 
      int P = 0; 
      while (P < 25) 
      { 
       Thread.Sleep(130); 
       progress?.Report(++P); 
      } 
     }  
    } 

Dieser verarbeitet Ihre lange laufende Aufgabe (Sleep in diesem Fall), in einen separaten Thread und den Wert über die Progress-Klasse wiederverwenden. Auf diese Weise wird Ihre GUI in GUI-Thread wie empfohlen aktualisiert und Sie erhalten die Updates entsprechend. Weiter wird es nicht empfohlen, Application.DoEvents(); zu verwenden, weil es viele pitfalls gibt, über die Sie wissen müssen.

+0

Wo heißt es _Application.DoEvents() Dies ist nur für Rückwärtskompatibilität und sollte nicht verwendet werden_? Nicht [hier] (https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents (v = vs.110) .aspx) zumindest :) – Pikoh

+0

@Pikoh Ich aktualisierte meine antworte und korrigiere es. Es kommt von VB 5.X, scheint aber auch in .Net in Ordnung zu sein. Es gibt nur einige Fallstricke, die Sie kennen und vermeiden sollten: http://StackOverflow.com/Questions/5181777/use-of-Application-doevents – Sebi

+0

Das ist besser. Wie auch immer, ich werde auch empfehlen, [diesen Link] (https://blog.codinghorror.com/is-doevents-evil/) zu lesen, der im Grunde dasselbe sagt, was ich bereits in meinen Kommentaren gesagt habe: für einfache Fälle wie für den einen Im OP-Beispiel ist die Verwendung von 'DoEvents()' vollkommen richtig. – Pikoh

Verwandte Themen