Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Progress bar using WPF with MVVM pattern (Using BackgroundWorker)

Note: This code works now. I have fixed some stupid mistake and I have also revised code as Steve Greatrex pointed out.

Original Posting LINK How to implement a progress bar using the MVVM pattern

ProgressbarSampleView.xaml

  <UserControl x:Class="MyProject.ProgressbarSampleView"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               Height="718" Width="1024">

  <ProgressBar Grid.Row="1" 
                 Value="{Binding CurrentProgress, Mode=OneWay}" 
                 Visibility="{Binding ProgressVisibility}" 
                 Margin="22,0,25,0" />

  <Button   Grid.Row="2"
            Content="Start Now"  
            Height="30" 
            Width="80" 
            HorizontalAlignment="Left" 
            Margin="22,4,0,0" 
            Name="btnStartNow" 
            VerticalAlignment="Top" 
            Command="{Binding Path=InstigateWorkCommand}" 
            />
  </UserControl>

ProggressbarSampleViewModel.cs

  namespace MyProject
  {
   public class ProggressbarSampleViewModel: ViewModelBase
   {
     private readonly BackgroundWorker worker; 
     private readonly ICommand instigateWorkCommand;

     public ProggressbarSampleViewModel()
     {
        this.instigateWorkCommand = new 
                      RelayCommand(o => this.worker.RunWorkerAsync(), o => !this.worker.IsBusy);
        this.worker = new BackgroundWorker();
        this.worker.DoWork += this.DoWork;
        this.worker.ProgressChanged += this.ProgressChanged;
    }


    public ICommand InstigateWorkCommand
    {
        get { return this.instigateWorkCommand; }
    }

    private int _currentProgress;
    public int CurrentProgress
    {
        get { return this._currentProgress; }
        private set
        {
            if (this._currentProgress != value)
            {
                this._currentProgress = value;
                OnPropertyChanged("CurrentProgress"); 
            }
        }
     }

     private void ProgressChanged(object sender, ProgressChangedEventArgs e)
     {
        this.CurrentProgress = e.ProgressPercentage;
     }

    private void DoWork(object sender, DoWorkEventArgs e)
    {
        // do time-consuming work here, calling ReportProgress as and when you can   
        for (int i = 0; i < 100; i++)
        {
            Thread.Sleep(1000);
            _currentProgress = i;
            OnPropertyChanged("CurrentProgress");
        }
    }

  }
like image 915
Shai Avatar asked Sep 14 '26 02:09

Shai


1 Answers

The StartNowCommand never invokes the BackgroundWorker - it just synchronously executes the DoStartNow method on the UI thread. Based on this, I'd guess that when you click on the button linked to the StartNow command you see your UI freeze up..?

You should be binding your button to the InstigateWorkCommand which actually runs BackgroundWorker code asynchronously.

In this implementation I don't think you would need the StartNowCommand at all. I also don't see the DoWork event handler anywhere in your view model, so I'm assuming that it just calls DoStartNow

like image 137
Steve Greatrex Avatar answered Sep 17 '26 00:09

Steve Greatrex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!