c# - 使用viewmodel在wpf窗口中实现进度条

标签 c# .net wpf mvvm

我有 wpf 窗口 (MainWindow .cs),它有按钮和进度条。

按钮绑定(bind)到我的 View 模型中的命令

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

进度条也绑定(bind)到 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    
}

我在想使用 this answer

所以我在同一个 View 模型中添加了
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 _IntigateWorkCommand;你不需要它,至少现在,它只会让你感到困惑。

在您的方法(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。线程完成。*

关于c# - 使用viewmodel在wpf窗口中实现进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25575164/

相关文章:

wpf - 处理加载的松散 Flowdocument 中的所有超链接 MouseEnter 事件

c# - 如何使用 MVVM 为用户偏好创建程序架构

wpf - 如何同步关闭 WPF 应用程序?

c# - Hangfire 多台服务器

.net - WCF 错误处理和访问类对象

c# - 实例化而不分配给变量

c# - 程序集特定设置未在运行时加载

.net - 您如何保护和计量您与业务合作伙伴共享的 Web 服务?

c# - XAML 中 Windows 8 商店应用程序中的 TreeView

c# - Nunit:是否可以让测试出现嵌套