I. Présentation▲
La barre de progression est un des moyens permettant de faire patienter l'utilisateur durant un traitement assez long. Un composant intégré au Dotnet permet d'en utiliser une mais elle comporte des limites, notamment graphiques.
II. Principe de fonctionnement▲
Le fonctionnement est assez simple, la barre par défaut comme les autres barres de progression ne sont pas dynamiques, dans le sens ou elles ne fonctionnent pas juste en les positionnant sur la scène, il faut aller un peu plus loin.
Le principe est de définir une unité de référence, par exemple, pour un traitement avec une base de données, l'unité pourra être le nombre de requête ou alors le nombre d'enregistrements d'une table. Il faut ensuite un nombre incrémenté représentant l'état actuel, par exemple, pour le même traitement avec la base de données, on prendra l'ID automatique de la table.
Le but est d'obtenir, à un instant donné, le pourcentage d'avancement du traitement. Dans notre exemple, nous allons travailler avec un Timer. L'unité de référence sera donc la seconde et le nombre incrémenté sera la somme des secondes qui se sont passées jusqu'à maintenant.
III. Timer utilisé pour l'exemple▲
Nous allons écrire la fonction représentant un traitement lourd en utilisant un Timer.
Pour commencer, déposer le composant Timer sur la scène, dans mon exemple, j'ai laissé le nom par défaut qui est "Timer1". J'écris ensuite la procédure qui permettra de simuler un traitement :
Dim
time
As
Interger =
0
Sub
Timer1_Tick
(
ByVal
sender As
System.Object
, ByVal
e As
System.EventArgs
) Handles Timer1.Tick
time
=
time
+
1
If
time
>
1000
Then
Timer1.Stop
(
)
End
If
End
Sub
Ce bout de code permet d'incrémenter le valeur de "time" de 1 en 1 jusqu'à se qu'il atteigne 1000. Cette action est exécutée toutes les 100 millisecondes par défaut mais vous pouvez faire varier ce paramètre grâce à la propriété Interval.
Ce code ne fonctionne pas encore, comme vous l'avez remarqué, le timer n'est pas encore démarré, il faut donc utiliser la méthode Start() afin de lancer le Timer1. Pour cela, nous ajoutons un bouton sur le formulaire que nous appelons Bouton1. Nous plaçons ensuite le code suivant sur l'événement Click :
Private
Sub
Button1_Click
(
ByVal
sender As
System.Object
, ByVal
e As
System.EventArgs
) Handles Button1.Click
Timer1.Start
(
)
End
Sub
Vous avez maintenant une petite application qui exécute un compteur de 1 à 1000 toutes les 100ms. Afin de vérifier si ce code fonctionne, vous pouvez toujours créer une TextBox et afficher la valeur de "time".
IV. Un peu de design▲
Passons aux choses sérieuses avec la partie design. Eh oui, eh oui ! Il n'y a pas que le code dans la vie. Dans le dossier de l'application, vous trouverez un dossier img qui stocke les sources de cet exemple. J'ai fait compliqué en utilisant six images mais vous pouvez le faire avec beaucoup moins.
Dans mon cas, il y a une barre de progression découpée en trois, ainsi qu'un fond aussi découpé en trois. Le but va être de faire une barre qui augmente progressivement. Pour cela, nous allons placer les extrémités de la barre puis faire varier la taille de celui du milieu.
Le fond sera de taille fixe et permettra de voir la taille maximum du chargement.
Vous avez maintenant une petite application qui exécute un compte de 1 à 1000 toutes les 100ms, afin de vérifier si ce code fonctionne, vous pouvez toujours créer une TextBox et afficher la valeur de "time".
V. Insérer les images à l'aide de PictureBox▲
Voyons comment insérer les images dans votre application. Vous devez créer six instances de PictureBox que vous nommez et leur attribuez une image, suivant le tableau ci-dessous :
Name | Image | BackgroundImage | SizeMode |
barre_L | leftBarre.png | AutoSize | |
barre_C | centerBarre.png | centerBarre.png | Normal |
barre_R | rightBarre.png | AutoSize | |
barre_bg_L | leftBg.png | AutoSize | |
barre_bg_C | centerBg.png | centerBg.png | Normal |
barre_bg_R | rightBg.png | AutoSize |
Nous venons de définir six PictureBox avec six images, les images center* utilisées au centre de la barre vont être redimensionnées, c'est pour cela qu'il ont des propriétés différentes comme le SizeMode en "normal".
Pour que la PictureBox est la bonne dimension, je vous conseille de configurer les images et de les passer en AutoSize (même les center*) puis ensuite, repasser les deux autres en normal.
VI. La fonction▲
On déclare une fonction permettant d'initialiser la progressbar, c'est-à-dire de la masquer avant le traitement, puis d'augmenter la tailler de la progressbar à chaque nouvelle incrémentation de la valeur de référence. Nous allons passer trois paramètres à cette fonction, la valeur courante du chiffre incrémenté, la valeur totale ou maxi, et la taille en pixel de la barre lorsque le chargement est complet.
Sub
pBarre
(
ByVal
i As
Integer
, ByVal
imax As
Integer
, ByVal
Wmax As
Integer
)
Nous allons ensuite faire un premier traitement, afin de masquer les éléments de la progressbar au chargement du formulaire. Pour cela, nous définissons que si la valeur est égale à 0, la fonction est uniquement appelée pour initialiser la barre. Sinon, il faut l'afficher.
If
i =
0
Then
'initialisation
barre_L.Visible
=
False
barre_C.Visible
=
False
barre_R.Visible
=
False
barre_bg_L.Visible
=
False
barre_bg_C.Visible
=
False
barre_bg_R.Visible
=
False
barre_lbl.Visible
=
False
Exit
Sub
' fin du traitement
Else
barre_L.Visible
=
True
barre_C.Visible
=
True
barre_R.Visible
=
True
barre_bg_L.Visible
=
True
barre_bg_C.Visible
=
True
barre_bg_R.Visible
=
True
End
If
Dans le cas où i vaut autre chose que 0, nous allons afficher les images en fonction des valeurs transmises à la fonction :
Dim
w As
Integer
'width : correspond à la taille actuelle du centre de la barre
Dim
p As
Integer
'pourcentage : correspond à l'état d'avancement du traitement
w =
Wmax *
(
i /
imax)
p =
100
*
(
i /
imax)
Maintenant que nous disposons d'une fonction qui détermine le pourcentage d'avancement ainsi que la taille actuelle de la barre, il ne reste plus qu'à placer les images de celle ci en fonction des valeurs calculées :
'on va déterminer la position des images en fonction de l'image barre_L
'on va ensuite définir la taille de l'image du milieu et placer l'image de droite en fonction d'elle
Dim
barreY As
Integer
=
barre_L.Location.Y
'alignement horizontal des images
barre_L.Location
=
New
Point
(
barre_L.Location.X
, barreY)
barre_C.Location
=
New
Point
(
barre_L.Location.X
+
barre_L.Width
, barreY)
barre_C.Width
=
w 'l'image du centre à la largeur w
barre_R.Location
=
New
Point
(
barre_C.Location.X
+
barre_C.Width
, barreY)
barre_bg_L.Location
=
New
Point
(
barre_L.Location.X
, barreY)
barre_bg_C.Location
=
New
Point
(
barre_bg_L.Location.X
+
barre_bg_L.Width
, barreY)
barre_bg_C.Width
=
Wmax +
10
'le fond prend la taille maxi avec une marge
barre_bg_R.Location
=
New
Point
(
barre_bg_C.Location.X
+
barre_bg_C.Width
, barreY)
'on va placer un label avec le pourcentage qui se placera sur la barre de chargement barre_lbl.Location = New Point(barre_R.Location.X - 15, barreY + 11)
barre_lbl.Text
=
p &
" %"
'N'oublions pas de fermer cette procédure :
End
Sub
Vous avez sûrement remarqué que le label était toujours masqué. J'ai choisi de l'afficher uniquement lorsque la barre est assez grande pour ne pas chevaucher le label. Il faut donc le rendre visible à condition que la valeur de w soit assez grande, introduisez le code suivant après avoir défini la valeur de w :
If
w >
15
Then
barre_lbl.Visible
=
True
End
If
Notre fonction est maintenant prêt à être appelée, revenons donc à notre traitement.
VII. Utilisation de la fonction pBarre()▲
Le traitement lourd simulé par notre Timer va permettre d'appeler notre fonction à chaque incrémentation. Mais avant tout, il faut l'initialiser, pour cela, nous allons nous placer sur l'événement Load du formulaire :
Sub
Form1_Load
(
ByVal
sender As
System.Object
, ByVal
e As
System.EventArgs
) Handles MyBase.Load
pBarre
(
0
, 0
, 0
) 'Initialise la barre
End
Sub
Nous pouvons maintenant utiliser la fonction pour notre traitement :
Private
Sub
Timer1_Tick
(
ByVal
sender As
System.Object
, ByVal
e As
System.EventArgs
) Handles Timer1.Tick
pBarre
(
time
, 1000
, 200
) 'valeurCourante , valeurMaxi , TailleMaxi
time
=
time
+
1
If
time
>
1000
Then
Timer1.Stop
(
) 'traitement terminé
End
If
End
Sub
VIII. Conclusion▲
Même si cet exemple n'a pas trop de sens, il vous apprend au moins à réfléchir sur la manière d'enrichir votre application avec de petites astuces comme la personnalisation d'un barre de progression. Faite preuve d'originalité dans vos logiciels et n'hésitez pas à créer vos propres 'composants'.
Vous pouvez utiliser cette barre dans vos programmes, n'hésitez pas à me le faire savoir si ce composant vous a servi, un petit mail me ferait un grand plaisir.
Concluons sur l'utilisation, il peut être judicieux d'utiliser une barre de progression pour le chargement d'un fichier (à chaque lignes, on augmente la barre, attention cela nécessite un comptage préalable du nombre de lignes), pour une requête SQL (une première requête envoie le nombre d'enregistrements, la suivante incrémentera la barre ligne par ligne), pour la création d'un treeview ou une dataTable (à chaque enregistrement, on incrémente) ou bien aussi pour la création ou lecture d'un fichier XML (à chaque Node, on incrémente).
Bref, à vous de l'adapter selon le traitement
IX. Remerciements▲
Je remercie tout particulièrement Alexandra, pour comprendre mon travail et pour me soutenir dans tout ce que je fais. Je t'aime.
Je remercie developpez.com pour donner aux développeurs la chance de s'exprimer, de s'entraider et de s'épanouir.
Je remercie les relecteurs qui ont travaillés sur cette page, tout particulièrement moi.