Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

ProgressBar avec un bouton Annuler

7 réponses
Avatar
SL3News
Bonjour,
Je souhaite implémenter un traitement affichant un ProgressBar avec un
bouton Annuler permettant d'annuler à tout moment le traitement.
J'utilise alors la procédure suivante :
- Création d'un formulaire FormProgressBar auquel j'ajoute le contrôle
progressBar1 ainsi qu'un bouton Annuler
- Utilisation de ce formulaire dans mon traitement tel que décrit ci-dessous
using (FormProgressBar f = new FormProgressBar())
{
f.progressBar1.Minimum = 0;
f.progressBar1.Maximum = 99999;
f.Show();
for (int i = 0; i < 99999; i++)
{
f.progressBar1.Value = i;
}
}

A l'exécution, la barre de progression s'affiche correctement et indique
bien le niveau d'avancement du traitement.
Par contre, le bouton Annuler ne s'affiche pas correctement : un rectangle
ayant comme couleur de fond la couleur de fond du formulaire appelant
s'affiche en lieu et place du bouton Annuler.
Par ailleurs, le click sur le bouton Annuler (disons plutôt la zone
rectangulaire du bouton) ne produit aucun effet. En fait il garde le click
en attente et l'applique simplement au contrôle du formulaire appelant se
trouvant à l'endroit où le bouton Annuler est censé s'afficher à la fin du
traitement.

Quelqu'un a-t-il une solution à mon problème?
Ou bien quelle est la meilleure procédure à suivre pour afficher
correctement une ProgressBar?

Merci d'avance pour vos contributions.

7 réponses

Avatar
Gilles TOURREAU
Le Sat, 22 Sep 2007 11:16:56 +0200, SL3News a écrit:

Bonjour,
Je souhaite implémenter un traitement affichant un ProgressBar avec un
bouton Annuler permettant d'annuler à tout moment le traitement.
J'utilise alors la procédure suivante :
- Création d'un formulaire FormProgressBar auquel j'ajoute le contrôle
progressBar1 ainsi qu'un bouton Annuler
- Utilisation de ce formulaire dans mon traitement tel que décrit
ci-dessous
using (FormProgressBar f = new FormProgressBar())
{
f.progressBar1.Minimum = 0;
f.progressBar1.Maximum = 99999;
f.Show();
for (int i = 0; i < 99999; i++)
{
f.progressBar1.Value = i;
}
}

A l'exécution, la barre de progression s'affiche correctement et indique
bien le niveau d'avancement du traitement.
Par contre, le bouton Annuler ne s'affiche pas correctement : un
rectangle
ayant comme couleur de fond la couleur de fond du formulaire appelant
s'affiche en lieu et place du bouton Annuler.
Par ailleurs, le click sur le bouton Annuler (disons plutôt la zone
rectangulaire du bouton) ne produit aucun effet. En fait il garde le
click
en attente et l'applique simplement au contrôle du formulaire appelant se
trouvant à l'endroit où le bouton Annuler est censé s'afficher à la fin
du
traitement.

Quelqu'un a-t-il une solution à mon problème?
Ou bien quelle est la meilleure procédure à suivre pour afficher
correctement une ProgressBar?

Merci d'avance pour vos contributions.





Lors de l'execution de votre boucle, Windows ne peut pas traiter les
autres messages de votre application (Clic sur un bouton, dessin des
contrôles...etc). Il faut donc forcer Windows à traiter ces messages en
attente...
Utilisez pour cela dans la boucle la méthode :

System.Windows.Forms.DoEvents()

Attention cependant à ne pas produire l'effet inverse (c'est à dire que
Windows passe plus de temps à traiter les messages en attente au lieu
d'executer votre code...)
Pour cela appelez cette méthode tous les 1% de progression par exemple...
Cela dépend bien évidemment de la durée de la progression et de la
complexité de votre code.

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Christophe Lephay
"SL3News" a écrit dans le message de news:
OMpoDiP$
Bonjour,
Je souhaite implémenter un traitement affichant un ProgressBar avec un
bouton Annuler permettant d'annuler à tout moment le traitement.
J'utilise alors la procédure suivante :
- Création d'un formulaire FormProgressBar auquel j'ajoute le contrôle
progressBar1 ainsi qu'un bouton Annuler
- Utilisation de ce formulaire dans mon traitement tel que décrit
ci-dessous
using (FormProgressBar f = new FormProgressBar())
{
f.progressBar1.Minimum = 0;
f.progressBar1.Maximum = 99999;
f.Show();
for (int i = 0; i < 99999; i++)
{
f.progressBar1.Value = i;
}
}

A l'exécution, la barre de progression s'affiche correctement et indique
bien le niveau d'avancement du traitement.
Par contre, le bouton Annuler ne s'affiche pas correctement : un rectangle
ayant comme couleur de fond la couleur de fond du formulaire appelant
s'affiche en lieu et place du bouton Annuler.
Par ailleurs, le click sur le bouton Annuler (disons plutôt la zone
rectangulaire du bouton) ne produit aucun effet. En fait il garde le click
en attente et l'applique simplement au contrôle du formulaire appelant se
trouvant à l'endroit où le bouton Annuler est censé s'afficher à la fin du
traitement.

Quelqu'un a-t-il une solution à mon problème?
Ou bien quelle est la meilleure procédure à suivre pour afficher
correctement une ProgressBar?

Merci d'avance pour vos contributions.



Ta fonction ne refile la main au système qu'à la fin de ta boucle. Il existe
une fonction pour la refiler (je connais pas son nom, cherche dans l'aide ou
sur msdn).

Tu devrais écrire ta boucle comme suit :

for( int i = 0; i < 1000; ++i)
for( int j = 0; j < 100; ++j )
{ LaFonctionQuiTraiteLesMessages(); f.progressBar1.Value = i*h; }
Avatar
cpasmwalolo
Oui DoEvents, c'est joli ! Les threads c'est encore mieux, et cela permet de
séparer la logique de la forme :-)



"SL3News" wrote in message
news:OMpoDiP$
Bonjour,
Je souhaite implémenter un traitement affichant un ProgressBar avec un
bouton Annuler permettant d'annuler à tout moment le traitement.
J'utilise alors la procédure suivante :
- Création d'un formulaire FormProgressBar auquel j'ajoute le contrôle
progressBar1 ainsi qu'un bouton Annuler
- Utilisation de ce formulaire dans mon traitement tel que décrit
ci-dessous
using (FormProgressBar f = new FormProgressBar())
{
f.progressBar1.Minimum = 0;
f.progressBar1.Maximum = 99999;
f.Show();
for (int i = 0; i < 99999; i++)
{
f.progressBar1.Value = i;
}
}

A l'exécution, la barre de progression s'affiche correctement et indique
bien le niveau d'avancement du traitement.
Par contre, le bouton Annuler ne s'affiche pas correctement : un rectangle
ayant comme couleur de fond la couleur de fond du formulaire appelant
s'affiche en lieu et place du bouton Annuler.
Par ailleurs, le click sur le bouton Annuler (disons plutôt la zone
rectangulaire du bouton) ne produit aucun effet. En fait il garde le click
en attente et l'applique simplement au contrôle du formulaire appelant se
trouvant à l'endroit où le bouton Annuler est censé s'afficher à la fin du
traitement.

Quelqu'un a-t-il une solution à mon problème?
Ou bien quelle est la meilleure procédure à suivre pour afficher
correctement une ProgressBar?

Merci d'avance pour vos contributions.




Avatar
Gilles TOURREAU
Le Sat, 22 Sep 2007 11:45:16 +0200,
a écrit:

Oui DoEvents, c'est joli ! Les threads c'est encore mieux, et cela
permet de
séparer la logique de la forme :-)



"SL3News" wrote in message
news:OMpoDiP$
Bonjour,
Je souhaite implémenter un traitement affichant un ProgressBar avec un
bouton Annuler permettant d'annuler à tout moment le traitement.
J'utilise alors la procédure suivante :
- Création d'un formulaire FormProgressBar auquel j'ajoute le contrôle
progressBar1 ainsi qu'un bouton Annuler
- Utilisation de ce formulaire dans mon traitement tel que décrit
ci-dessous
using (FormProgressBar f = new FormProgressBar())
{
f.progressBar1.Minimum = 0;
f.progressBar1.Maximum = 99999;
f.Show();
for (int i = 0; i < 99999; i++)
{
f.progressBar1.Value = i;
}
}

A l'exécution, la barre de progression s'affiche correctement et indique
bien le niveau d'avancement du traitement.
Par contre, le bouton Annuler ne s'affiche pas correctement : un
rectangle
ayant comme couleur de fond la couleur de fond du formulaire appelant
s'affiche en lieu et place du bouton Annuler.
Par ailleurs, le click sur le bouton Annuler (disons plutôt la zone
rectangulaire du bouton) ne produit aucun effet. En fait il garde le
click
en attente et l'applique simplement au contrôle du formulaire appelant
se
trouvant à l'endroit où le bouton Annuler est censé s'afficher à la fin
du
traitement.

Quelqu'un a-t-il une solution à mon problème?
Ou bien quelle est la meilleure procédure à suivre pour afficher
correctement une ProgressBar?

Merci d'avance pour vos contributions.









C'est utile uniquement dans le cas où l'on souhaite faire un traitement
"en arrière plan"...

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Martin CLAVREUIL
Salut,

Pourquoi ne pas utiliser un backgroundworker ?
http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx


SL3News a écrit :
Bonjour,
Je souhaite implémenter un traitement affichant un ProgressBar avec un
bouton Annuler permettant d'annuler à tout moment le traitement.
J'utilise alors la procédure suivante :
- Création d'un formulaire FormProgressBar auquel j'ajoute le contrôle
progressBar1 ainsi qu'un bouton Annuler
- Utilisation de ce formulaire dans mon traitement tel que décrit ci-dessous
using (FormProgressBar f = new FormProgressBar())
{
f.progressBar1.Minimum = 0;
f.progressBar1.Maximum = 99999;
f.Show();
for (int i = 0; i < 99999; i++)
{
f.progressBar1.Value = i;
}
}

A l'exécution, la barre de progression s'affiche correctement et indique
bien le niveau d'avancement du traitement.
Par contre, le bouton Annuler ne s'affiche pas correctement : un rectangle
ayant comme couleur de fond la couleur de fond du formulaire appelant
s'affiche en lieu et place du bouton Annuler.
Par ailleurs, le click sur le bouton Annuler (disons plutôt la zone
rectangulaire du bouton) ne produit aucun effet. En fait il garde le click
en attente et l'applique simplement au contrôle du formulaire appelant se
trouvant à l'endroit où le bouton Annuler est censé s'afficher à la fin du
traitement.

Quelqu'un a-t-il une solution à mon problème?
Ou bien quelle est la meilleure procédure à suivre pour afficher
correctement une ProgressBar?

Merci d'avance pour vos contributions.




Avatar
Christophe Lephay
"Martin CLAVREUIL" a écrit dans le message de news:
u0MCYyT$
Salut,

Pourquoi ne pas utiliser un backgroundworker ?
http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx



De toute façon, le thread devra soit incrémenter la progressbar (marshaling)
soit appeler DoEvent. L'affichage n'étant mis à jour que dans le thread
principal (si j'ai bien compris - je découvre c#), créer un nouveau thread
ne permettra pas, dans un cas comme dans l'autre, de résoudre le problème du
posteur initial.
Avatar
Martin CLAVREUIL
Ok, la version complète :

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e)
{
for (int i = 0; i < 100 && !e.Cancel; i++)
{
//Cette ligne simule un traitement long (100 fois en fait)
System.Threading.Thread.Sleep(300);
backgroundWorker1.ReportProgress(i);
if (backgroundWorker1.CancellationPending) e.Cancel = true;
}
e.Result = true;
}

private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
CancelButton.Enabled = true;
button1.Enabled = false;
}

private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

private void CancelButton_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
CancelButton.Enabled = false;
}

private void backgroundWorker1_RunWorkerCompleted(object
sender, RunWorkerCompletedEventArgs e)
{
CancelButton.Enabled = false;
button1.Enabled = true;
}
}


Christophe Lephay a écrit :
"Martin CLAVREUIL" a écrit dans le message de news:
u0MCYyT$
Salut,

Pourquoi ne pas utiliser un backgroundworker ?
http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx



De toute façon, le thread devra soit incrémenter la progressbar (marshaling)
soit appeler DoEvent. L'affichage n'étant mis à jour que dans le thread
principal (si j'ai bien compris - je découvre c#), créer un nouveau thread
ne permettra pas, dans un cas comme dans l'autre, de résoudre le problème du
posteur initial.