wake-up-neo.com

Wie zeige ich in Winforms eine Meldung "Loading ... please wait" für ein langes Ladeformular an?

Ich habe ein Formular, das sehr langsam ist, da das Formular viele Steuerelemente enthält. 

Daher dauert das Laden des Formulars sehr lange. 

Wie lade ich das Formular zuerst, dann zeige es an und zeige während des Ladevorgangs ein anderes Formular mit der Nachricht "Laden ... bitte warten"

41
Sadegh

Die Verwendung eines separaten Threads zum Anzeigen einer einfachen Please wait-Nachricht ist übertrieben, insbesondere wenn Sie nicht viel Erfahrung mit dem Threading haben.

Eine wesentlich einfachere Methode besteht darin, ein "Bitte warten" -Formular zu erstellen und es vor dem langsamen Laden als ein Fenster ohne Modus anzuzeigen. Wenn das Hauptformular fertig geladen ist, blenden Sie bitte das Warteformular aus.

Auf diese Weise verwenden Sie nur den einen Haupt-UI-Thread, um zuerst das bitte warten-Formular anzuzeigen und dann Ihr Hauptformular zu laden. 

Die einzige Einschränkung bei diesem Ansatz besteht darin, dass Ihr please wait-Formular nicht animiert werden kann (z. B. eine animierte GIF), da der Thread gerade das Hauptformular lädt.

PleaseWaitForm pleaseWait=new PleaseWaitForm ();

// Display form modelessly
pleaseWait.Show();

//  ALlow main UI thread to properly display please wait form.
Application.DoEvents();

// Show or load the main form.
mainForm.ShowDialog();
52
Ash

Ich habe mir die Lösungen am besten angesehen, aber ich habe eine andere gefunden, die mir lieber ist. Es ist einfach, verwendet keine Threads und funktioniert so, wie ich es möchte.

http://weblogs.asp.net/kennykerr/archive/2004/11/26/where-is-form-s-loaded-event.aspx

Ich habe die Lösung in dem Artikel hinzugefügt und den Code in eine Basisklasse verschoben, von der alle meine Formulare erben. Jetzt rufe ich nur eine Funktion auf: ShowWaitForm () während des Ereignisses frm_load () eines Formulars, das ein Wartedialogfeld benötigt, während das Formular geladen wird. Hier ist der Code:

public class MyFormBase : System.Windows.Forms.Form
{
    private MyWaitForm _waitForm;

    protected void ShowWaitForm(string message)
    {
        // don't display more than one wait form at a time
        if (_waitForm != null && !_waitForm.IsDisposed) 
        {
            return;
        }

        _waitForm = new MyWaitForm();
        _waitForm.SetMessage(message); // "Loading data. Please wait..."
        _waitForm.TopMost = true;
        _waitForm.StartPosition = FormStartPosition.CenterScreen;
        _waitForm.Show();
        _waitForm.Refresh();

        // force the wait window to display for at least 700ms so it doesn't just flash on the screen
        System.Threading.Thread.Sleep(700);         
        Application.Idle += OnLoaded;
    }

    private void OnLoaded(object sender, EventArgs e)
    {
        Application.Idle -= OnLoaded;
        _waitForm.Close();
    }
}

MyWaitForm ist der Name eines Formulars, das Sie wie ein Wartedialogfeld erstellen. Ich habe eine SetMessage () - Funktion hinzugefügt, um den Text auf dem Warten-Formular anzupassen.

23
goku_da_master

Sie möchten sich die Splash-Bildschirme ansehen.

Zeigen Sie ein weiteres 'Splash'-Formular an und warten Sie, bis die Verarbeitung abgeschlossen ist.

Hier ist ein kurzer und schmutziger post , wie es geht.

Hier ist ein besseres Beispiel .

18
David Basarab

Eine andere Möglichkeit, "Ladebildschirm" nur zu einem bestimmten Zeitpunkt anzuzeigen, besteht darin, es vor dem Ereignis zu platzieren und es nach Beendigung des Ereignisses zu schließen.

Beispiel: Sie möchten ein Ladeformular für ein Ereignis zum Speichern des Ergebnisses als MS Excel-Datei anzeigen und nach Abschluss der Verarbeitung verwerfen. Gehen Sie folgendermaßen vor:

LoadingWindow loadingWindow = new LoadingWindow();

try
{
    loadingWindow.Show();                
    this.exportToExcelfile();
    loadingWindow.Close();
}
catch (Exception ex)
{
    MessageBox.Show("Exception EXPORT: " + ex.Message);
}

Oder Sie können loadingWindow.Close() in den finally-Block einfügen.

10
ahmadnaziF

Eine einfache Lösung:

using (Form2 f2 = new Form2())
{
    f2.Show();
    f2.Update();

    System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here

Und ersetzen Sie dann Ihre Ladung für den Schlaf.
Dies blockiert absichtlich den UI-Thread. 

7
Henk Holterman

Sie sollten einen Hintergrund-Thread erstellen, um das Formular zu erstellen und zu füllen. Dadurch kann der Vordergrund-Thread die Lademeldung anzeigen.

5
unholysampler

Sie können einen Blick auf die Implementierung des Begrüßungsbildschirms werfen: C # winforms-Startup (Splash), das nicht verbirgt

4
Grzenio

Der beste Ansatz, wenn Sie auch ein animiertes Bild haben, ist dieses:

1- Sie müssen eine "WaitForm" erstellen, die die Methode empfängt, die im Hintergrund ausgeführt wird. Wie dieser

public partial class WaitForm : Form
{
    private readonly MethodInvoker method;

    public WaitForm(MethodInvoker action)
    {
        InitializeComponent();
        method = action;
    }

    private void WaitForm_Load(object sender, EventArgs e)
    {
        new Thread(() =>
        {
            method.Invoke();
            InvokeAction(this, Dispose);
        }).Start();
    }

    public static void InvokeAction(Control control, MethodInvoker action)
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(action);
        }
        else
        {
            action();
        }
    }
}

2 - Sie können das Waitform so verwenden

private void btnShowWait_Click(object sender, EventArgs e)
{
    new WaitForm(() => /*Simulate long task*/ Thread.Sleep(2000)).ShowDialog();
}
3

Ich habe einige animierte GIFs in eine Form namens FormWait gesetzt und diese dann als:

// show the form
new Thread(() => new FormWait().ShowDialog()).Start();

// do the heavy stuff here

// get the form reference back and close it
FormWait f = new FormWait();
f = (FormWait)Application.OpenForms["FormWait"];
f.Close();
3
Daniel Bonetti

Nun, ich mache so etwas.

NormalWaitDialog/*your wait form*/ _frmWaitDialog = null;

//For static wait dialog
//On an Event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += async (s, e) =>
{
   Refresh();
   await Task.Run(() =>
   {
      //Do your stuff
   });
_frmWaitDialog.Close();
};
_frmWaitDialog.ShowDialog(this);



//For animated wait dialog
//On an event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += (s, e) =>
{
   //create a async method and call the method here
   LoadDataAsync();
};
_frmWaitDialog.ShowDialog(this);

 //Async Method
 private async void LoadDataAsync(){
       await Task.Run(() =>
       {
          //Do your stuff
       });
       _frmWaitDialog.Close();
 }
3

wenn Sie keine Lust auf Animationen usw. haben, können Sie ein Etikett erstellen und an das Formular andocken, um den Z-Index von Dokumentumrissfenster in 0 zu ändern und ihm eine Hintergrundfarbe zu geben, sodass andere Steuerelemente nicht sichtbar sind als ausgeführt. Application.DoEvents() Einmal im Formular laden Sie das Ereignis und führen Sie alle Codierungen in dem angezeigten Ereignis aus. Wenn Sie das Ereignis und das angezeigte Ereignis festlegen, setzen Sie Ihre Eigenschaft visible auf false, und führen Sie dann erneut Application.DoEvents() aus.

1
trksyln

Ich weiß, dass es sehr spät ist, aber ich habe dieses Projekt gegründet und möchte es mit Ihnen teilen, es ist sehr nützlich und einfach Simple Display Dialog of Waiting in WinForms

0
ajd.nas