2 Stimmen

Text des Labels nicht aktualisiert

Ich habe ein Windows-Formular mit einer Statusleiste, die den aktuellen Zustand der Anwendung anzeigt. Ich habe eine Klasse namens AppState, die das Label in der Statusleiste aktualisiert und im Dispos-Methode den Zustand auf "Bereit" zurücksetzt.

Im Code, wenn ich eine Operation wie diese durchführe:

using (AppState state = new AppState("Verarbeitung..."))
{
     //Führe einige Arbeiten aus, die einige Sekunden dauern
}

Aber das Label bleibt gleich. Es treten keine Ausnahmen auf. Der Label-Text wird aktualisiert, aber in der Benutzeroberfläche wird weiterhin der vorherige Wert angezeigt. Fehlt mir etwas?

santosc du hast recht, das ist das Einzige, was ich mache. Hier ist der AppState-Code

public class AppState : IDisposable
{
    static string Default = "Bereit";

    public AppState(string status)
    {
        Form.StatusLabel.Text = status;
    }

    public void Dispose()
    {
        Form.StatusLabel.Text = Default;
    }
}

5voto

Oliver Punkte 41055

Es ist immer dasselbe...

Wenn Sie etwas starten möchten, das eine Weile dauert, tun Sie es nicht innerhalb Ihres GUI-Threads, sonst wird Ihr GUI einfrieren (keine Aktualisierungen des Labels, keine Größenänderung, kein Verschieben, was auch immer).

Es ist auch eine schlechte Praxis, Ihren Code an tausend Stellen mit Application.DoEvents() zu füllen.

Wenn Sie eine lang laufende Aufgabe haben (lang bedeutet > 1 Sekunde), sollten Sie wahrscheinlich einen BackgroundWorker verwenden. Am Anfang ist es vielleicht etwas schwieriger, aber Sie werden es lieben, wenn Ihr Programm komplexer wird. Da dies bereits mehrmals diskutiert wurde, hier ist ein Link mit einigen Beispielscode.

Jetzt, da Sie das richtige Werkzeug (BackgroundWorker) kennen, um Ihr Problem zu lösen, sollten Sie es zum Laufen bringen (oder eine andere Frage zu Ihrem neuen spezifischen Problem stellen).

4voto

Jeremy McGee Punkte 24034

Es sieht so aus, als wollten Sie Application.DoEvents() nach dem Setzen des Werts des StatusLabel Textfelds platzieren. Dies sagt Windows Forms, die Windows-Ereigniswarteschlange für Ihr Formular zu verarbeiten, was dazu führt, dass Änderungen neu gezeichnet werden.

2voto

serhio Punkte 27312

Um "thread-safe" zu sein, verwenden Sie Invoke und testen Sie mit dem InvokeRequired in der Form wie:

// Code außerhalb des myForm:-----------------------
if (myForm.InvokeRequired)
    myForm.Invoke(new ChangeLabelEventHandler(ChangeLabel), "teeeest");
else
    myForm.ChangeLabel("teeeest");

// Code im myForm:-----------------------------
public delegate void ChangeLabelEventHandler(string newText);

private void ChangeLabel(string newLabelText)
{
    this.label1.Text = newLabelText;
}

2voto

mrduclaw Punkte 3814

Ich bin neu in C# Sachen, aber warum kannst du nicht einfach so etwas machen:

private void updateStatusBar(string status)
{
    if (StatusLabel.InvokeRequired)
    {
        StatusLabel.Invoke((MethodInvoker)(() =>
                   {
                       StatusLabel.Text = status;
                   }));
    }
    else
    {
         StatusLabel.Text = status;
    }
}

Wann möchtest du den Status aktualisieren?

0voto

Matthias Punkte 11592

Vielleicht könnten mehrere Threads Ihr Problem lösen.

Der einfachste Weg ist die Verwendung eines BackgroundWorkers.

Der Grund dafür ist, dass die Benutzeroberfläche nur dann neu gezeichnet werden kann, wenn der UI-Thread nichts anderes zu tun hat. Und Sie blockieren ihn mit Ihrer Berechnung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X