2017-04-11 3 views
-1

Guten Morgen Leute, ich versuche, eine Anwendung in C# zu schreiben, wo ich die UI (ein Fortschrittsbalken in diesem Fall) von einem anderen Thread und Klasse zu aktualisieren.C# update UI von anderer Klasse/Thread

Aber ich kann es einfach nicht zur Arbeit bringen, ich google und suche herum, aber ich fürchte, ich verstehe es einfach nicht. Ich habe eine Windows-Formularanwendung, ich starte einen Thread, wenn ich auf eine Schaltfläche klicke, und irgendwo in diesem Thread möchte ich meine Benutzeroberfläche aktualisieren.

I entweder erhalten: Eine Objektreferenz für die nicht-statisches Feld erforderlich ist, eine Methode oder eine Eigenschaft oder etwas in der Richtung des Objekts von einem anderen Thread erstellt wurde. (An dem Ort, an dem ich versuche, Form1.UpdateProgressBar (Wert); in FileReader) aufzurufen.

Ich habe keine Erfahrung in der objektorientierenden Programmierung, ich bleibe normalerweise bei C. Wenn mir jemand den richtigen Weg dazu sagen könnte, wäre ich sehr glücklich.

Edit_1: In Ordnung .. Kombinationen von Fehlern, die Antwort konnte bisher geholfen haben, wenn ich nicht statisches Problem hatte. Und die statische Ausgabe Festlegung die gesamte Klasse statisch zu machen erzeugt eine weiteren X Menge von Fehlern auf seinem eigenen, einschließlich:

Statische Klassen nicht Instanzkonstruktoren

namespace TestCode 
{ 

    public partial class Form1 : Form 
    { 
    static fileReader SourceReader; 
    public Thread SearchThread { get; set; } 

    public Form1() 
    { 
     InitializeComponent(); 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     folderBrowserDialog1.ShowDialog(); 
     Console.WriteLine(folderBrowserDialog1.SelectedPath); 

     this.SearchThread = new Thread(new ThreadStart(this.ThreadProcSafe)); 
     this.SearchThread.Start(); 
    } 


    public void UpdateProgressBar(int value) 
    { 

     progressBar1.Value =value; 

    } 

    private void ThreadProcSafe() 
    { 
     SourceReader = new fileReader(folderBrowserDialog1.SelectedPath); 
    } 
    } 
} 

Klasse 2 haben:

 namespace TestCode 
    { 
     class fileReader 
     { 

      public fileReader(String path) 
      { 
       int value = 20; 
       /*Do some stuff*/ 
        Form1.UpdateProgressBar(value); 

      } 

      } 

    } 
+0

Ihre fileReader-Klasse ist nicht st Aus diesem Grund sagt der Compiler, dass Sie einen Verweis auf diese Klasse benötigen, bevor Sie den Konstruktor aufrufen. –

+1

Dies ist ein schlechtes Design. 'fileReader' sollte nicht von' Forms' abhängen. Schauen Sie sich die Verwendung von 'Task' und' IProgress 'für eine bessere Fortschrittsbenachrichtigung an. Beispiel: https://blogs.msdn.microsoft.com/dotnet/2012/06/06/asyncin-in-4-5-enabling-progress-and-cancellation-in-async-apis/ – user3185569

Antwort

-1

Sie können einen MethodInvoker verwenden, wenn Sie versuchen, die UI von einer anderen Klasse wie der folgenden zu ändern:

ProgressBar progressBar = Form1.progressBar1; 
MethodInvoker action =() => progressBar.Value = 80; 
progressBar.BeginInvoke(action); 

, während Sie können dies nutzen, wenn sie in einem anderen Thread (ein Task zum Beispiel) arbeiten:

progressBar1.Invoke((Action)(() => progressBar1.Value=50)) 

Aber die Kommentare zu Ihrem Beitrag betrachten. Es ist nicht zu abhängig von Forms in fileReader

Exkurs benötigt: Ich weiß nicht, wie Sie das Problem nicht auf hier gefunden:

how to update a windows form GUI from another class?

How to update the GUI from another thread in C#?

0

Überprüfen Sie, ob ein Aufruf erforderlich ist und inf benötigt dann verwenden Sie die Steuerelemente Invoke-Funktion:

public void UpdateProgressBar(int value) 
{ 
    if(progressBar1.InvokeRequired){ 
     progressBar1.Invoke(new MethodInvoker(() => progressBar1.Value=value)); 
    }else{ 
     progressBar1.Value =value; 
    } 
}