簡體   English   中英

使用ViewModel在WPF窗口中實現進度欄

[英]implementing progress bar in wpf window with viewmodel

我有WPF窗口( MainWindow .cs),它具有按鈕和進度條。

按鈕綁定到我的視圖模型中的命令

<Button Command="{Binding StartMyWork}" Content="Run" Width="200" Height="50"/>

進度條也綁定到ViewModel中的CurrentProgress屬性

<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}"  Width="400"/>

MainWindowViewModel.cs

private ICommand _StartMyWork;
public ICommand StartMyWork;
{ 
    get {
         if (_StartMyWork == null) {
                _StartMyWork = new RelayCommand(
                       x => this.DoSomeDummyWork(this.MySelectedComboValue)
                );
          }
          return _StartMyWork;
     }
}

private void DoSomeDummyWork(string mySelectedComboProp)
{
    // here I want to simulate some work
    // and make ui responsive and introduce progressbar    
}

我在想用這個答案

所以我添加了相同的視圖模型

private ICommand _InstigateWorkCommand;
private double _CurrentProgress;
private BackgroundWorker _Worker;

private void DoSomeDummyWork(string mySelectedComboProp)
{
    // here I want to simulate some work
    // and make ui responsive and introduce progressbar
     _InstigateWorkCommand = new RelayCommand(x => _Worker.RunWorkerAsync(),  x => !_Worker.IsBusy);
     _Worker = new BackgroundWorker();
     _Worker.DoWork += DoWork;
     _Worker.ProgressChanged += this.ProgressChanged;   
}

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

public double CurrentProgress
{
    get { return _CurrentProgress; }
    private set {
         if (_CurrentProgress != value){
            _CurrentProgress = value;
            OnPropertyChanged("CurrentProgress");
         }
    }
}

private void DoWork(object sender, DoWorkEventArgs e)
{
   for (int i = 0; i < 10; i++) {
       Thread.Sleep(1000);
       _CurrentProgress = i;
   }
}

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

在實現進度條時我錯了的地方,我在DoWork方法中設置了斷點,盡管第一個命令StartMyWork可以按預期工作,但它從未被擊中。

首先,刪除第二個命令ICommand _InstigateWorkCommand; 您不需要它,至少到目前為止,它只會使您感到困惑。

在執行第一個命令的方法(DoSomeDummyWork)中 ,刪除這些lambda表達式行_InstigateWorkCommand = new RelayCommand(x => _Worker.RunWorkerAsync(),x =>!_Worker.IsBusy);
並把這個

 _Worker = new BackgroundWorker();
 _Worker.WorkerReportsProgress = true;
 _Worker.DoWork += DoWork;                        
 _Worker.ProgressChanged += new ProgressChangedEventHandler(ProgressChanged);
_Worker.RunWorkerAsync();

DoWork方法也應該像這樣

private void DoWork(object sender, DoWorkEventArgs e)
{
  for (int i = 0; i < 10; i++)
   {
    Thread.Sleep(1000);
    _Worker.ReportProgress(i*(100/10));          
  }            
}

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

您現在還應該添加方法,一旦迭代完成,該方法將被調用

void workerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    MessageBox.Show("Complete!");
}

並連線此方法

_Worker.RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(workerCompleted);

*僅提及RunWorkerCompleted事件將觸發,無論bg如何。 線程已完成-正常完成還是拋出異常(取消操作)。 雖然如果您關閉應用程序的同時bg。 運行該應用程序的工作人員將立即退出,而無需等待bg。 線程完成。*

您需要通過某種交互來激活_InstigateWorkCommand,否則您將永遠不會開始實際的更新。 如果您想停止使用_InstigateWorkCommand並在單擊綁定到StartMyWork的按鈕時將其啟動,則需要將RunWorkerAsync代碼從RelayCommand綁定上移一個級別。

例如:

private void DoSomeDummyWork(string mySelectedComboProp)
{
    // here I want to simulate some work
    // and make ui responsive and introduce progressbar
     _Worker = new BackgroundWorker();
     _Worker.DoWork += DoWork;
     _Worker.ProgressChanged += this.ProgressChanged; 
     _Worker.RunWorkerAsync();
}

哦,還不完整。 如Maximus所說,在您的DoSomeDummyWork方法的末尾添加_Worker.RunWorkerAsync() 然后:

private void DoWork(object sender, DoWorkEventArgs e)
{
   for (int i = 0; i < 10; i++) {
       Thread.Sleep(1000);
       _CurrentProgress = i;
   }
}

不是_CurrentProgress ,而是CurrentProgress 它將通知您的ProgressBar有關更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM