web-dev-qa-db-fra.com

Faire une mise à jour de la barre de progression en temps réel dans wpf

J'ai du mal à faire en sorte que la barre de progression affiche les mises à jour en temps réel.

C'est mon code en ce moment

for (int i = 0; i < 100; i++)
{
     progressbar1.Value = i;
     Thread.Sleep(100);
}

Mais pour une raison quelconque, la barre de progression affiche vide lorsque la fonction s'exécute, puis rien jusqu'à ce que la fonction se termine. Quelqu'un peut-il m'expliquer comment cela peut être fait? Je suis nouveau sur C #/WPF, donc je ne suis pas sûr à 100% de la façon dont j'implémenterais un répartiteur sur un autre thread (comme on le voit sur certains autres messages) pour résoudre ce problème.

Pour clarifier, mon programme a un bouton qui, lorsque vous appuyez sur, saisit la valeur d'une zone de texte et utilise une API pour récupérer des informations et créer des étiquettes en fonction de celles-ci. Je souhaite que la barre de progression soit mise à jour une fois le traitement de chaque ligne de données terminé.

Voici ce que j'ai en ce moment:

private async void search(object sender, RoutedEventArgs e)
{
    var progress = new Progress<int>(value => progressbar1.Value = value);
    await Task.Run(() =>
    {
        this.Dispatcher.Invoke((Action)(() =>
        {
             some pre-processing before the actual for loop occur
             for (int i = 0; i < numberofRows; i++)
             {
                  label creation + adding
                  ((IProgress<int>)progress).Report(i);
             }
        }));
    });
}

Merci!

16
nonion

A réussi à le faire fonctionner. Tout ce que je devais faire, c'est au lieu de le faire juste

progressBar1.value = i;

Je devais juste faire

progressbar1.Dispatcher.Invoke(() => progressbar1.Value = i, DispatcherPriority.Background);
22
nonion

Si vous utilisez .NET 4.5 ou version ultérieure, vous pouvez utiliser async/wait :

var progress = new Progress<int>(value => progressBar.Value = value);
await Task.Run(() =>
{
    for (int i = 0; i < 100; i++)
    {
        ((IProgress<int>)progress).Report(i);
        Thread.Sleep(100);
    }
});

Vous devez marquer votre méthode avec le mot clé async pour pouvoir utiliser await, par exemple:

private async void Button_Click(object sender, RoutedEventArgs e)
27
Aleksey Shubin

Vous devez utiliser BackgroundWorker inclus dans .NET, qui vous fournit des méthodes pour signaler la progression d'un thread d'arrière-plan dans un événement. Le thread qui a créé le BackGroundWorker appelle automatiquement cet événement.

BackgroundWorker.ProgressChanged peut être utilisé pour signaler à l'utilisateur la progression d'une opération asynchrone.

// This event handler updates the progress bar. 
private void backgroundWorker1_ProgressChanged(object sender,
    ProgressChangedEventArgs e)
{
    this.progressBar1.Value = e.ProgressPercentage;
}

Reportez-vous à MSDN pour plus d'informations sur son utilisation.

5
Saagar Elias Jacky