web-dev-qa-db-fra.com

Comment puis-je afficher un message "Chargement en cours ... veuillez patienter" dans Winforms pour un formulaire de chargement long?

J'ai un formulaire qui est très lent car il y a beaucoup de contrôles placés sur le formulaire. 

En conséquence, le formulaire prend beaucoup de temps à charger. 

Comment puis-je charger le formulaire en premier lieu, puis l'afficher et pendant le chargement, afficher un autre formulaire contenant le message "Chargement ... veuillez patienter.?"

41
Sadegh

L'utilisation d'un fil séparé pour afficher un simple message, veuillez patienter, est excessive, surtout si vous n'avez pas beaucoup d'expérience avec le filetage.

Une approche beaucoup plus simple consiste à créer un formulaire "Veuillez patienter" et à l'afficher sous forme de fenêtre sans mode juste avant le formulaire à chargement lent. Une fois le chargement du formulaire principal terminé, masquez le formulaire en attente.

De cette manière, vous utilisez uniquement l'unique thread principal de l'interface utilisateur pour afficher d'abord le formulaire en cours, veuillez patienter, puis chargez votre formulaire principal. 

La seule limite à cette approche est que votre formulaire d'attente, veuillez patienter, ne peut pas être animé (comme un fichier GIF animé) car le thread est en train de charger votre formulaire principal.

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

J'ai examiné la plupart des solutions publiées, mais en ai trouvé une différente que je préfère. C'est simple, n'utilise pas de threads et fonctionne pour ce que je veux.

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

J'ai ajouté à la solution de l'article et déplacé le code dans une classe de base dont tous mes formulaires héritent. Maintenant, je viens d'appeler une fonction: ShowWaitForm () pendant l'événement frm_load () de tout formulaire nécessitant une boîte de dialogue d'attente pendant le chargement du formulaire. Voici le 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 est le nom d'un formulaire que vous avez créé pour ressembler à un dialogue d'attente. J'ai ajouté une fonction SetMessage () pour personnaliser le texte du formulaire d'attente.

23
goku_da_master

Vous voulez examiner les écrans «Splash».

Affichez un autre formulaire «Splash» et attendez que le traitement soit terminé.

Voici un rapide/sale post sur la façon de le faire.

Voici un meilleur exemple .

18
David Basarab

Une autre façon d’afficher «Écran de chargement» à un moment donné est de le placer avant l’événement et de le rejeter une fois l’événement terminé.

Par exemple: vous souhaitez afficher un formulaire de chargement pour un événement d’enregistrement du résultat en tant que fichier MS Excel et le supprimer après le traitement terminé, procédez comme suit:

LoadingWindow loadingWindow = new LoadingWindow();

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

Ou vous pouvez mettre loadingWindow.Close() dans le bloc finally.

10
ahmadnaziF

Une solution simple:

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

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

Et substituez ensuite votre chargement au sommeil.
Cela bloque volontairement le thread d'interface utilisateur. 

7
Henk Holterman

Vous devez créer un fil d’arrière-plan pour créer et remplir le formulaire. Cela permettra à votre fil de premier plan d’afficher le message de chargement.

5
unholysampler

Vous pouvez jeter un coup d'œil à la mise en œuvre de mon écran de démarrage: C # winforms startup form (Splash) ne se cache pas

4
Grzenio

La meilleure approche lorsque vous avez également une image animée est la suivante:

1- Vous devez créer un "WaitForm" qui reçoit la méthode qu'il exécutera en arrière-plan. Comme celui-ci

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 - Vous pouvez utiliser le Waitform comme ceci

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

J'ai mis un gif animé dans un formulaire appelé FormWait et je l'ai ensuite appelé:

// 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

Eh bien, je le fais quelque chose comme ça.

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

ou si vous ne voulez rien d’animé comme de l’animation, etc., vous pouvez créer une étiquette et l’ancrer pour la former, puis changer son index z en fenêtre de contour du document en 0 et lui donner une couleur d’arrière-plan afin que les autres contrôles ne soient pas visibles par rapport à l'exécution Application.DoEvents(). une fois dans l'événement de chargement de formulaire et effectuez tous les codages dans l'événement de formulaire affiché et, à la fin de l'événement affiché, définissez votre propriété visible de l'étiquette sur false, puis exécutez à nouveau Application.DoEvents().

1
trksyln

Je sais qu’il est très tard, mais j’ai fondé ce projet et j’aimerais le partager avec vous. Il est très utile et donnez un exemple Le dialogue simple d’affichage en attente dans WinForms

0
ajd.nas