Реализация индикатора выполнения с использованием WPF с шаблоном MVVM (с использованием BackgroundWorker) - PullRequest
3 голосов
/ 07 октября 2011

Примечание: этот код работает сейчас. Я исправил некоторую глупую ошибку, и я также пересмотрел код, как указал Стив Грейтрекс.

Original Posting LINK Как реализовать индикатор выполнения с использованием шаблона MVVM

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");
        }
    }

  }

1 Ответ

1 голос
/ 07 октября 2011

StartNowCommand никогда не вызывает BackgroundWorker - он просто синхронно выполняет метод DoStartNow в потоке пользовательского интерфейса.Исходя из этого, я предполагаю, что когда вы нажимаете кнопку, связанную с командой StartNow, вы видите, что ваш пользовательский интерфейс зависает ..?

Вы должны привязать свою кнопку к InstigateWorkCommand, который на самом делевыполняет BackgroundWorker код асинхронно.

В этой реализации я не думаю, что вам вообще понадобится StartNowCommand.Я также не вижу обработчик событий DoWork в вашей модели представления, поэтому я предполагаю, что он просто вызывает DoStartNow

...