web-dev-qa-db-fra.com

WPF Progressbar s'arrête après quelques barres

Dans mon application WPF, je dois montrer une progression de la barre de progression avec un événement de minuterie, que j'écris comme ci-dessous,

System.Windows.Forms.Timer timer;
public MainWindow()
{
    timer = new System.Windows.Forms.Timer();
    timer.Interval = 1000;
    this.timer.Tick += new System.EventHandler(this.timer_Tick);
}

charger l'événement comme ci-dessous

private void Window_Loaded(object sender, RoutedEventArgs e)
{
      progressBar1.Minimum = 0;
      progressBar1.Value = DateTime.Now.Second;
      progressBar1.Maximum = 700;
      timer.Start();         
 }

Et enfin en cas de tick,

private void timer_Tick(object sender, EventArgs e)
{
    Duration duration = new Duration(TimeSpan.FromSeconds(20));

    //progress bar animation
    System.Windows.Media.Animation.DoubleAnimation doubleanimation = new    System.Windows.Media.Animation.DoubleAnimation(200.0, duration);
    progressBar1.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);
}

Lorsque la barre de progression du programme affiche la progression de deux à trois barres, puis elle arrête l'incrémentation. Plus tard, il n'y a aucun effet sur les progrès.

Pourquoi?

13
Sangeetha

Dans mon [~ # ~] wpf [~ # ~] application, j'ai ... System.Windows.Forms.Timer timer;

Ce n'est pas le bon type de temporisateur. Utilisez plutôt un DispatcherTimer .

Quand j'exécute la barre de progression de mon programme montre la progression de deux à trois barres, puis elle s'arrête

Cela me surprend, je ne m'attendais pas du tout à ce que cela fonctionne. Cela signifie que vous pouvez également avoir d'autres problèmes, comme bloquer le thread principal (répartiteur).

Vous ne définissez la valeur qu'une seule fois, dans l'événement Loaded:

     progressBar1.Value = DateTime.Now.Second;

Il n'y a aucun changement à progressBar1.Value dans l'événement Tick. Donc, il suppose qu'il cesse de bouger.

9
Henk Holterman

Puisque votre ProgressBar ne se rapporte à aucun comportement particulier, il ressemble à un travail pour une barre indéterminée .

Cette autre SO question donne un aperçu à ce sujet. En bref, c'est une doublure XAML:

<!-- MinVal, MaxVal, Height needed for this to work -->
<ProgressBar x:Name="progressBar1" Margin="5" IsIndeterminate="True" 
    MinimumValue="0" MaximumValue="700" value="0" Height="20"/> 

Ensuite, dans le code, vous allez comme ceci:

progressBar1.IsIndeterminate = true; // start animation
progressBar1.IsIndeterminate = false; // stop animation
10
Alex

Utilisez DispatcherTimer au lieu de Timer (objet Forms) et utilisez la propriété Value de ProgressBar.

Essaye ça :

MainWindows.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="55" Width="261">
    <Grid>
        <ProgressBar Name="pb" Maximum="60" />
    </Grid>
</Window>

MainWindows.xaml.cs:

using System.Windows;
using System.Windows.Threading;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        private DispatcherTimer timer;

        public MainWindow()
        {
            InitializeComponent();

            this.timer = new DispatcherTimer();
            this.timer.Tick += timer_Tick;
            this.timer.Interval = new System.TimeSpan(0, 0, 1);
            this.timer.Start();
        }

        private void timer_Tick(object sender, System.EventArgs e)
        {
            this.pb.Value = System.DateTime.Now.Second % 100;
        }
    }
}

Vous pouvez changer le comportement de la barre de progression en modifiant la propriété Value (n'oubliez pas la propriété Maximum définie dans le xaml).

4
Xaruth

J'ai trouvé que ( WPF Multithreading: Utilisation de BackgroundWorker et Reporting the Progress to the UI. Link ) contenait une excellente solution pour mes besoins, bien qu'avec une boîte de dialogue.

La seule chose que j'ai trouvée très utile était que le thread de travail ne pouvait pas accéder aux contrôles de MainWindow (dans sa propre méthode), cependant, lors de l'utilisation d'un délégué à l'intérieur du gestionnaire d'événements Windows principal, c'était possible.

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    pd.Close();
    // Get a result from the asynchronous worker
    T t = (t)args.Result
    this.ExampleControl.Text = t.BlaBla;
};
3
lko