【发布时间】:2011-04-01 00:37:19
【问题描述】:
我有一个基于 MVVM 设计模式的 WPF 应用程序。
我希望在应用中实现一个进度条,遵循 MVVM 模式。
有人对如何实现这一点有任何建议吗?
提前致谢
【问题讨论】:
我有一个基于 MVVM 设计模式的 WPF 应用程序。
我希望在应用中实现一个进度条,遵循 MVVM 模式。
有人对如何实现这一点有任何建议吗?
提前致谢
【问题讨论】:
通常,您的 UI 会简单地绑定到 VM 中的属性:
<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}"
Visibility="{Binding ProgressVisibility}"/>
您的 VM 将使用 BackgroundWorker 在后台线程上执行工作,并定期更新 CurrentProgress 值。像这样的:
public class MyViewModel : ViewModel
{
private readonly BackgroundWorker worker;
private readonly ICommand instigateWorkCommand;
private int currentProgress;
public MyViewModel()
{
this.instigateWorkCommand =
new DelegateCommand(o => this.worker.RunWorkerAsync(),
o => !this.worker.IsBusy);
this.worker = new BackgroundWorker();
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
}
// your UI binds to this command in order to kick off the work
public ICommand InstigateWorkCommand
{
get { return this.instigateWorkCommand; }
}
public int CurrentProgress
{
get { return this.currentProgress; }
private set
{
if (this.currentProgress != value)
{
this.currentProgress = value;
this.OnPropertyChanged(() => this.CurrentProgress);
}
}
}
private void DoWork(object sender, DoWorkEventArgs e)
{
// do time-consuming work here, calling ReportProgress as and when you can
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.CurrentProgress = e.ProgressPercentage;
}
}
【讨论】:
CurrentProgress 的设置器必须是公共的,或者必须在进度条上明确指定OneWay 模式绑定。默认值似乎是 TwoWay(对于 Progressbar 来说很奇怪),因此绑定引擎使用私有设置器抛出异常。 2) 使用ReportProgress 时,似乎有必要将BackgroundWorker 的WorkerReportsProgress 属性设置为true。否则线程执行静默停止(无异常,仅在RunWorkerCompleted事件参数中可见)。
使用ProgressBar 控件并将其Value 属性绑定到ViewModel 的属性:
查看
<ProgressBar Minimum="0" Maximum="0" Value="{Binding CurrentProgress}" />
视图模型
private double _currentProgress;
public double CurrentProgress
{
get { return _currentProgress; }
private set
{
_currentProgress = value;
OnPropertyChanged("CurrentProgress");
}
}
【讨论】:
IsIndeterminate 设置为 true,并在 ViewModel 中使用 bool 属性来隐藏/显示进度条。
向您的虚拟机添加两个属性:
bool IsProgressBarVisible
double ProgressValue
如果您在 VM 中启动长时间操作,请将 IsProgressBarVisible-property 设置为 true,并将 ProgressValue periodical 设置为当前进度值。尝试计算 0 到 100 之间的值。这样做的好处是您不必提供最小值和最大值。 异步操作完成后,将 IsProgressBarVisible 设置为 false。
在 XAML 中,绑定到这两个属性。使用值转换器将布尔可见性转换为可见性。
<ProgressBar Value="{Binding ProgressValue}" Visibility="{Binding IsProgressBarVisible,Converter={StaticResource BooleanToVisibility_ValueConverter}}"/>
【讨论】: