yayou49
Messages postés7Date d'inscriptionlundi 17 février 2014StatutMembreDernière intervention30 mars 2015
-
Modifié par yayou49 le 19/03/2015 à 16:58
yayou49
Messages postés7Date d'inscriptionlundi 17 février 2014StatutMembreDernière intervention30 mars 2015
-
30 mars 2015 à 11:39
Bonjour,
Pour faire simple, J'ai une Form qui exécute du code chronophage et je souhaiterai ajouter une Progress bar pendant le temps d'exécution.
Mon problème c'est que la Progress bar ne se met à jour qu'a la fin de l'exécution du long traitement.
J'ai vu ici et là que l'utilisation d'un BackgroundWorker pouvait résoudre le problème. Malheureusement, je ne m'en sort pas et j'aurai donc besoin de votre aide.
Une petite précision: je ne souhaite pas faire évoluer la progress bar au fils du temps mais juste l'afficher avec une valeur max(-1) pour visualiser le petit mouvement auto-généré par cette progress bar tant qu'elle n'est pas au max (ce qui explique pourquoi j'ai indiqué max(-1)).
Posons les bases de l'exemple:
J'ai une Form nommée Form1
Sur cette form, j'ai:
- un bouton nommé "BtGo"
- une progress bar nommée "Pb" avec visible = false.
Voici le code qui correspond à ce que je souhaiterai faire:
Public Class Form1
Private Sub BtGo_Click(sender As System.Object, e As System.EventArgs) Handles BtGo.Click
'Appel du démarrage de la progress bar (parametre = True) Barre(True)
'// appel à la sub de traitement chronophage '// '//
'Appel de l'arret de la progress bar (parametre = False) Barre(False)
End Sub Private Sub Barre(ByVal Start As Boolean)
If Start = True Then
'*** Paramétrage de la Progress Bar *** Pb.Minimum = 0 Pb.Maximum = 5000 Pb.Value = 4999 'Valeur maximum - 1 Dim Pos As New System.Drawing.Point Pos.X = 0 Pos.Y = 10 Pb.Location = Pos 'on defini la largeur de la barre, égale à la largeur de la form. Pb.Width = Me.Width Pb.Visible = True 'parce que la progress bar est visible(false) dans la form
'et c'est là que je ne sais plus quoi faire car ma progress bar ne s'affichera complete qu'a la fin du traitement chronophage............
Else Pb.Visible = False End If
End Sub
End Class
Voila, j'espère que mon problème est expliqué clairement et que vos réponses pourront éclairer ma lanterne.
cs_Le Pivert
Messages postés7893Date d'inscriptionjeudi 13 septembre 2007StatutContributeurDernière intervention19 mai 2023136 21 mars 2015 à 08:26
Cela ne peut pas fonctionner pour 2 raisons:
1)Tu ne peux pas appeler Private Sub Barre(ByVal Start As Boolean) tel qu'il est d'un autre Form que celui dans lequel il a été écrit.
2)Pour que la ProgressBar fonctionne en même temps que l'action qui s'effectue, il faut un thread d'arrière plan. C'est pour cela que l'on utilise unBackgroundWorker
guatto
Messages postés12Date d'inscriptionjeudi 19 mars 2015StatutMembreDernière intervention 1 juin 2016 19 mars 2015 à 17:53
Bonsoir Yannick,
si je crois comprendre ce que tu veux faire, tu esseayes d'avoir la PB affichée avec value.max = -1 au final mais dans le commentaire du code, tu as dit "ma progress bar ne s'affichera complete qu'a la fin du traitement chronophage" ! c'est normal parce que tu as mis (Pb.Visible = True) en dernier !
je ne sais pas si c'est ça ton problème mais j'aimerais bien t'aider si tu éclaires ma lanterne !
yayou49
Messages postés7Date d'inscriptionlundi 17 février 2014StatutMembreDernière intervention30 mars 2015 19 mars 2015 à 18:05
Bonsoir Guatto,
ce n'est pas value.max = -1 mais pb.value = max-1
dans l'exemple c'est 5000-1 donc 4999
(j'aurai pu écrire pb.value = pb.maximum - 1, ce qui revenait au même)
En ce qui concerne le pb.visible = true, même si je le met au début du paramétrage de la PB, cela ne change rien.
C'est l'ensemble du code qui se trouve après "if start = true" qui ne s'exécute (malheureusement) qu'à la fin du traitement chronophage et non pas avant.
Quand je click sur le BtGo, il devrait d'abord initialiser la PB et la rendre visible puis ensuite exécuter le traitement chronophage puis rendre la PB non visible.
cs_Le Pivert
Messages postés7893Date d'inscriptionjeudi 13 septembre 2007StatutContributeurDernière intervention19 mai 2023136 19 mars 2015 à 18:42
Bonjour,
Avec un BackgroundWorker, voici le code:
Imports System.ComponentModel' je ne me rappelle pas si c'est nécessaire
#Region "Thread"
Private Sub BtGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdcreer.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim MyThread As BackgroundWorker = CType(sender, BackgroundWorker) 'récupération du thread d'arrière plan
Dim pourcent As Integer
MyThread.ReportProgress(pourcent) 'pourcent est un Integer indiquant l'état d'avancement.
'mettre l'action a effectuer
End Sub
Private Sub BackgroundWorker1_ProgressChanged( _
ByVal sender As Object, _
ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
ProgressBar1.Style = ProgressBarStyle.Marquee
End Sub
'Quand le code d'arrière plan est terminé la procédure RunWorkerCompleted est exécutée.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
ProgressBar1.Style = ProgressBarStyle.Blocks
ProgressBar1.Value = 100
' ici, elle affiche un message indiquant que le thread d'arrière plan est terminé.
MessageBox.Show("Opération réussie ", "Action a effectuer", MessageBoxButtons.OK, MessageBoxIcon.Information)
cmdsave.Enabled = True
cmdcreer.Enabled = False
End Sub
yayou49
Messages postés7Date d'inscriptionlundi 17 février 2014StatutMembreDernière intervention30 mars 2015 19 mars 2015 à 22:56
merci le pivert pour cette réponse.
J'essaye le code dés lundi et je ferai un feedback.
yayou49
Messages postés7Date d'inscriptionlundi 17 février 2014StatutMembreDernière intervention30 mars 2015 20 mars 2015 à 19:09
Je n'est pas encore eu le temps de tester le code, mais en le lisant je comprend bien le mode de fonctionnement et je pense que dans ce cas cela fonctionne.
Ceci étant dit, j'aurai une petite variante de mon probleme à soumettre car je ne pense pas que dans ce cas, cette solution fonctionne.
Donc, on prend la form1 comme décrit, mais on supprime le BtGo de la form et du code.
On créé une form2 qui inherite de la form1.
Dans cette form2, on met le bouton BtGo avec le même code que celui qui était dans la form1.
Cela donne pour la form1::
Public Class Form1
Private Sub Barre(ByVal Start As Boolean)
If Start = True Then
'*** Paramétrage de la Progress Bar *** Pb.Minimum = 0 Pb.Maximum = 5000 Pb.Value = 4999 'Valeur maximum - 1 Dim Pos As New System.Drawing.Point Pos.X = 0 Pos.Y = 10 Pb.Location = Pos 'on defini la largeur de la barre, égale à la largeur de la form. Pb.Width = Me.Width Pb.Visible = True 'parce que la progress bar est visible(false) dans la form
'et c'est là que je ne sais plus quoi faire car ma progress bar ne s'affichera complete qu'a la fin du traitement chronophage............
Else Pb.Visible = False End If
End Sub
End Class
et pour la form2:
Public Class Form2 inherit form1
Private Sub BtGo_Click(sender As System.Object, e As System.EventArgs) Handles BtGo.Click
'Appel du démarrage de la progress bar (parametre = True) Barre(True)
'// appel à la sub de traitement chronophage '// '//
'Appel de l'arret de la progress bar (parametre = False) Barre(False)
End Sub
End Class
L'objectif est de ne pas modifier le code qui se trouve dans le BtGo et de gérer l'affichage de cette fameuse progress Bar.
J'espere avoir une réponse aussi efficace que la premiere ^^ ;)
yayou49
Messages postés7Date d'inscriptionlundi 17 février 2014StatutMembreDernière intervention30 mars 2015 30 mars 2015 à 11:39
pour ceux que ça intéresse, voici le code qui permet de faire ce que j'ai demandé:
Form1:
Imports System.Threading
Public Class Form1
Private mThread As Thread Public Sub DemarrerTraitement(tache As action) mThread = New Thread(New ThreadStart(Sub() Me.Invoke(Sub(ctrl As Form1) DebutTraitement(ctrl), New Object() {Me}) tache.Invoke() Me.Invoke(Sub(ctrl As Form1) FinTraitement(ctrl), New Object() {Me}) End Sub )) mThread.Start()
End Sub
Private Sub DebutTraitement(window As Form1) window.Barre(True) End Sub
Private Sub FinTraitement(window As Form1) window.Barre(False) End Sub
Public Sub Barre(ByVal Start As Boolean)
If Start = True Then
'*** Paramétrage de la Progress Bar *** Pb.Minimum = 0 Pb.Maximum = 5000 Pb.Value = 4999 'Valeur maximum - 1 Dim Pos As New System.Drawing.Point Pos.X = 0 Pos.Y = 10 Pb.Location = Pos 'on defini la largeur de la barre, égale à la largeur de la form. Pb.Width = Me.Width Pb.Visible = True 'parce que la progress bar est visible(false) dans la form1
Else Pb.Visible = False End If
End Sub
End Class
et Form2:
Imports System.Threading Public Class Form2 Inherits Form1
Private Sub BtGo_Click(sender As System.Object, e As System.EventArgs) Handles BtGo.Click
DemarrerTraitement(New Action(Sub()
'appel au traitement long '....... For i = 1 To 100 Thread.Sleep(100) Next '.......