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.?"
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();
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.
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
.
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.
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.
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
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();
}
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();
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();
}
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()
.
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