J'ai décidé d'utiliser ce composant tiers pour effectuer un contrôle de chargement simple dans mon formulaire Windows.
http://www.codeproject.com/Articles/14841/How-to-write-a-loading-circle-animation-in-NET
Cela fonctionne très bien lors de l'activation et de la désactivation de la modification de la propriété "Active" à true ou false dans une seule demande (une par fois). Le problème est lorsqu'un processus attend d'être servi, et je fais semblant d'activer le loadingControl avant que le processus ne démarre et je m'éteins lorsque je "pense" que le processus doit être terminé. Quand je le fais, le chargement de l'image est affiché comme une image statique. (Sans animation).
Je suis désolé pour cette question, je suis nouveau en C #. Mais je pense que je dois utiliser des threads ou quelque chose de similaire.
Donc, mon code général est le suivant:
using [libraries here]...;
namespace [namespace here]
{
Public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.loadingCircle1.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(showLoading));
this.loadingCircle1.Visible = true;
t.Start();
//Import an Excel
t.Abort();
}
public void showLoading()
{
loadingCircle1.Active = true;
loadingCircle1.RotationSpeed = 10;
}
}
}
Mais toujours le chargement s'affiche comme une image statique sans l'animation.
Vous créez un thread, qui définit simplement deux propriétés, puis se termine. Le t.Abort
ne fera probablement rien, puisque le thread aura été quitté à ce moment-là. Pire encore, vous importez le fichier Excel sur le thread d'interface utilisateur, ce qui bloque toute animation et fige l'interface utilisateur complète.
Voici comment vous devez le faire:
Remarque: Bien sûr, si votre formulaire est réactif, vous devez désactiver/activer les contrôles et préparer au cas ce qui se passe si votre formulaire est fermé pendant la charge.
1. Utilisation de threads
Si vous voulez vraiment utiliser explicitement des threads, faites-le comme ceci:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Thread workerThread = null;
private void btnImport_Click(object sender, EventArgs e)
{
// start the animation (I used a progress bar, start your circle here)
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;
// start the job and the timer, which polls the thread
btnImport.Enabled = false;
workerThread = new Thread(LoadExcel);
workerThread.Start();
timer1.Interval = 100;
timer1.Start();
}
private void LoadExcel()
{
// some work takes 5 sec
Thread.Sleep(5000);
}
private void timer1_Tick(object sender, EventArgs e)
{
if (workerThread == null)
{
timer1.Stop();
return;
}
// still works: exiting
if (workerThread.IsAlive)
return;
// finished
btnImport.Enabled = true;
timer1.Stop();
progressBar1.Visible = false;
workerThread = null;
}
}
2. Travailleur d'arrière-plan
BackgroundWorker
peut lancer un événement lorsqu'il est terminé:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;
}
private void btnImport_Click(object sender, EventArgs e)
{
// start the animation
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;
// start the job
btnImport.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
LoadExcel();
}
private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnImport.Enabled = true;
progressBar1.Visible = false;
}
private void LoadExcel()
{
// some work takes 5 sec
Thread.Sleep(5000);
}
}
. Utilisation de async-wait
Ceci est le plus simple.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void btnImport_Click(object sender, EventArgs e)
{
// start the waiting animation
progressBar1.Visible = true;
progressBar1.Style = ProgressBarStyle.Marquee;
// simply start and await the loading task
btnImport.Enabled = false;
await Task.Run(() => LoadExcel());
// re-enable things
btnImport.Enabled = true;
progressBar1.Visible = false;
}
private void LoadExcel()
{
// some work takes 5 sec
Thread.Sleep(5000);
}
}
Je recommanderais d'utiliser async/wait (pour C # 5.0):
private void button1_Click(object sender, EventArgs e){
ImportAsync();
}
private async Task ImportAsync(){
// UI-thread
showLoading();
this.loadingCircle1.Visible = true;
// wait until task will be finished
await Task.Run(() => {
// different non-blocking thread for all the hard work, but without UI-stuff
// import an Excel
});
// going back to UI-thread
this.loadingCircle1.Visible = false;
}