TOC

This article has been localized into French by the community.

Contrôles divers:

Le contrôle ProgressBar

WPF est livré avec un contrôle pratique pour afficher la progression, appelé ProgressBar. Il fonctionne en réglant une valeur minimum et maximum et ensuite incrémenter une valeur, ce qui donnera une indication visuelle de l'état actuel du processus. Voici un exemple très simple pour le démontrer :

<Window x:Class="WpfTutorialSamples.Misc_controls.ProgressBarSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ProgressBarSample" Height="100" Width="300">
    <Grid Margin="20">
        <ProgressBar Minimum="0" Maximum="100" Value="75" />
    </Grid>
</Window>

Dans cet exemple, j'ai utilisé une approche assez standard pour montrer le progrès en pourcentage (entre 0 et 100%) et lui donnant une valeur initiale de 75. Une autre approche est d'utiliser les valeurs minimales et maximales réelles d'une liste de tâches que vous effectuez. Par exemple, si vous effectuez une boucle sur une liste collectée de fichiers tout en vérifiant chacun d'entre eux, vous pouvez mettre la propriété Minimum à 0, le Maximum à la quantité de fichiers dans votre liste, et ensuite incrémenter au fur et à mesure que votre boucle parcourt la liste des fichiers.

La barre de progression est, tout comme les autres contrôles WPF standard, rendue pour correspondre au style visuel du système d'exploitation. Ici, sous Windows 7, elle possède une belle interface de dégradé animé, comme on peut le voir sur la capture d'écran.

Afficher la progression durant l'exécution d'une tâche de longue haleine

L'exemple ci-dessus illustre à quel point il est simple d'utiliser une ProgressBar, mais normalement vous voudriez bien sûr montrer l'avancement d'un travail réel et non pas juste une valeur statique.

Dans la plupart des situations, vous utiliserez la ProgressBar pour montrer la progression d'une tâche lourde/longue, et c'est là que la plupart des nouveaux programmeurs se heurtent à un problème très commun : Si vous faites un travail lourd sur le thread de l'interface utilisateur, tout en essayant de mettre à jour simultanément, par exemple un contrôle ProgressBar, vous allez vite réaliser qu'on ne peut pas faire les deux, en même temps, sur le même Thread. Ou pour être plus clair, vous pouvez le faire, mais la ProgressBar n'affichera pas réellement chaque mise à jour de l'élément avant que la tâche ne soit terminée, ce qui la rend pratiquement inutile.

Pour illustrer cela, vous pouvez essayer l'exemple suivant :

<Window x:Class="WpfTutorialSamples.Misc_controls.ProgressBarTaskOnUiThread"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ProgressBarTaskOnUiThread" Height="100" Width="300"
        ContentRendered="Window_ContentRendered">
    <Grid Margin="20">
        <ProgressBar Minimum="0" Maximum="100" Name="pbStatus" />
    </Grid>
</Window>
using System;
using System.Threading;
using System.Windows;

namespace WpfTutorialSamples.Misc_controls
{
	public partial class ProgressBarTaskOnUiThread : Window
	{
		public ProgressBarTaskOnUiThread()
		{
			InitializeComponent();
		}

		private void Window_ContentRendered(object sender, EventArgs e)
		{
			for(int i = 0; i < 100; i++)
			{
				pbStatus.Value++;
				Thread.Sleep(100);
			}
		}
	}
}

Un exemple très basique, où, dès que la fenêtre est prête, on fait une boucle de 0 à 100 et à chaque itération, on incrémente la valeur de la ProgressBar. N'importe quel ordinateur moderne peut le faire plus vite que vous ne pouvez cligner des yeux, j'ai donc ajouté un délai à chaque itération de 100 millisecondes. Malheureusement, comme je l'ai déjà décrit, il ne se passera rien. Voici à quoi cela ressemble au milieu du processus :

Notez que le curseur indique que quelque chose est en train de se produire, mais que la barre ProgressBar ressemble toujours à ce qu'elle était au début (vide). Dès que la boucle qui représente notre longue tâche est terminée, la ProgressBar ressemblera à ceci :

Cela n'a pas vraiment aidé vos utilisateurs à voir les progrès ! Au lieu de cela, nous devons effectuer la tâche sur un thread ouvrier et ensuite pousser les mises à jour vers le thread UI, qui sera alors en mesure de traiter immédiatement ces mises à jour et de les afficher visuellement. Un excellent outil pour gérer ce travail est la classe BackgroundWorker, dont nous parlerons plus en détail ailleurs dans ce tutoriel. Voici le même exemple que ci-dessus, mais cette fois en utilisant un BackgroundWorker :

<Window x:Class="WpfTutorialSamples.Misc_controls.ProgressBarTaskOnWorkerThread"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ProgressBarTaskOnWorkerThread" Height="100" Width="300"
        ContentRendered="Window_ContentRendered">
    <Grid Margin="20">
        <ProgressBar Minimum="0" Maximum="100" Name="pbStatus" />
    </Grid>
</Window>
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;

namespace WpfTutorialSamples.Misc_controls
{
	public partial class ProgressBarTaskOnWorkerThread : Window
	{
		public ProgressBarTaskOnWorkerThread()
		{
			InitializeComponent();
		}

		private void Window_ContentRendered(object sender, EventArgs e)
		{
			BackgroundWorker worker = new BackgroundWorker();
			worker.WorkerReportsProgress = true;
			worker.DoWork += worker_DoWork;
			worker.ProgressChanged += worker_ProgressChanged;

			worker.RunWorkerAsync();
		}

		void worker_DoWork(object sender, DoWorkEventArgs e)
		{
			for(int i = 0; i < 100; i++)
			{
				(sender as BackgroundWorker).ReportProgress(i);
				Thread.Sleep(100);
			}
		}

		void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			pbStatus.Value = e.ProgressPercentage;
		}
	}
}

Comme vous pouvez le voir sur la capture d'écran, la progression est maintenant mise à jour tout au long de la tâche, et comme l'indique le curseur, aucun travail difficile n'est effectué sur le thread UI, ce qui signifie que vous pouvez toujours interagir avec le reste de l'interface.

Sachez que bien que le BackgroundWorker aide beaucoup avec les problèmes liés au multithreading, il y a encore certaines choses dont vous devriez être conscient. Pour cela jetez un coup d'œil aux articles sur le BackgroundWorker de ce tutoriel avant de faire quoi que ce soit de plus avancé qu'un scénario comme celui ci-dessus.

Indéterminée

Pour certaines tâches, il n'est pas possible d'exprimer les progrès en pourcentage ou vous ne savez tout simplement pas combien de temps cela prendra. Pour ces situations, la ProgressBar indéterminée a été inventée, où une animation permet à l'utilisateur de savoir qu'il se passe quelque chose, tout en indiquant que le temps de fonctionnement ne peut être déterminé.

La barre de progression WPF ProgressBar prend en charge ce mode grâce à l'utilisation de la propriété IsIndeterminate, que nous allons vous montrer dans l'exemple suivant :

<Window x:Class="WpfTutorialSamples.Misc_controls.ProgressBarIndeterminateSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ProgressBarIndeterminateSample" Height="100" Width="300">
    <Grid Margin="20">
        <ProgressBar Minimum="0" Maximum="100" Name="pbStatus" IsIndeterminate="True" />
    </Grid>
</Window>

Notez que l'indicateur de progression vert n'est pas ancré sur l'un ou l'autre des côtés - au lieu de cela, il flotte librement du début à la fin, puis il recommence.

ProgressBar avec texte

Une chose qu'il manque à la ProgressBar standard WPF est la possibilité de montrer une représentation textuelle de la progression ainsi que la barre de progression. Heureusement pour nous, la flexibilité de WPF nous facilite la tâche. En voici un exemple :

<Window x:Class="WpfTutorialSamples.Misc_controls.ProgressBarTextSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ProgressBarTextSample" Height="100" Width="300">
    <Grid Margin="20">
        <ProgressBar Minimum="0" Maximum="100" Value="75" Name="pbStatus" />
        <TextBlock Text="{Binding ElementName=pbStatus, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</Window>

Nous accomplissons ce qui précède en mettant la ProgressBar et le bloc de texte montrant le pourcentage à l'intérieur de la même Grid, sans spécifier de lignes ou de colonnes. Cela affichera le TextBlock au-dessus de la barre de progression, ce qui est exactement ce que nous voulons ici, car le TextBlock a un fond transparent par défaut.

Nous utilisons une liaison pour nous assurer que le TextBlock affiche la même valeur que la barre de progression. Notez la syntaxe spéciale StringFormat, qui nous permet d'afficher la valeur avec un signe de pourcentage. Cela peut sembler un peu étrange, mais s'il vous plaît allez voir l'article StringFormat pour plus d'informations à ce sujet.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!