1. 程式人生 > >【WPF】The example of progress bar, label status changed by background worker

【WPF】The example of progress bar, label status changed by background worker

Demo screenshot;


xaml source code:

<Window x:Class="CommonTesting.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ProcessDisplay" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Name="lblDisplay" />
        <ProgressBar Grid.Row="1" Name="pgbPrinting" />
        <Button Grid.Row="2" Name="btnPrint" Content="Print" Click="btnPrint_Click" />
        <Button Grid.Row="3" Name="btnPause" Content="Pause" IsEnabled="False" Click="btnPause_Click" />
        <Button Grid.Row="4" Name="btnCancel" Content="Cancel" IsEnabled="False" Click="btnCancel_Click" />
    </Grid>
</Window>

cs source code:

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

namespace CommonTesting
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private BackgroundWorker _worker = new BackgroundWorker();
        private ManualResetEvent _manualReset = new ManualResetEvent(true);
        private bool _isPause = false;

        public MainWindow()
        {
            InitializeComponent();
            _worker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
            _worker.WorkerSupportsCancellation = true;

            //for progress bar
            _worker.WorkerReportsProgress = true;
            _worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
        }

        void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            pgbPrinting.Value = e.ProgressPercentage;
        }

        void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                this.Dispatcher.Invoke(new Action(() => {
                    lblDisplay.Content = "Cancel...";
                    pgbPrinting.Value = 0;
                }));
            }
            else if (e.Error != null)
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    lblDisplay.Content = "Error...";
                    pgbPrinting.Value = 0;
                }));
            }
            else
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    lblDisplay.Content = "Completed...";
                }));
            }

            btnPrint.IsEnabled = true;
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            this.Dispatcher.Invoke(new Action(() => {
                lblDisplay.Content = "Start...";
            }));

            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                if (_worker.CancellationPending)
                {
                    //receive cancellation message
                    e.Cancel = true;
                    return;
                }

                _manualReset.WaitOne();

                _worker.ReportProgress(i + 1);
            }
        }

        private void btnPrint_Click(object sender, RoutedEventArgs e)
        {
            btnPrint.IsEnabled = false;
            btnCancel.IsEnabled = btnPause.IsEnabled = true;

            _worker.RunWorkerAsync();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            btnPrint.IsEnabled = true;
            btnCancel.IsEnabled = btnPause.IsEnabled = false;
            if (_isPause)
            {
                PauseToggle();
            }

            _worker.CancelAsync();
        }

        private void btnPause_Click(object sender, RoutedEventArgs e)
        {
            PauseToggle();
        }

        private void PauseToggle()
        {
            _isPause = !_isPause;
            if (_isPause)
            {
                _manualReset.Reset();
                btnPause.Content = "Continue";
                lblDisplay.Content = "Pause...";
            }
            else
            {
                _manualReset.Set();
                btnPause.Content = "Pause";
                lblDisplay.Content = "Start...";
            }
        }
    }
}