我有 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/