我制作了一些 UI,其中有 ProgressBar。使用MVVM模式。
XAML:
<ProgressBar Grid.Row="2" Minimum="0" Maximum="100" Value="{Binding CurrentProgress, Mode=OneWay}"/>
视图模型(简化):
class MyClass : ViewModelBase
{
/// <summary>
/// Fields
/// </summary>
private int _currentProgress;
private readonly BackgroundWorker _worker;
private int _step;
/// <summary>
/// Properties
/// </summary>
public int CurrentProgress
{
get
{
return _currentProgress;
}
set
{
if (_currentProgress != value)
{
_currentProgress = value;
RaisePropertyChanged("CurrentProgress");
}
}
}
/// <summary>
/// Constructor
/// </summary>
public MyClass()
{
_step = 10;
_currentProgress = 0;
_worker = new BackgroundWorker();
_worker.DoWork += DoWork;
_worker.WorkerReportsProgress = true;
_worker.ProgressChanged += ProgressChanged;
_worker.RunWorkerCompleted += RunWorkerCompleted;
}
/// <summary>
/// Command
/// </summary>
private RelayCommand _myCommand;
public RelayCommand MyCommand
{
get
{
return _myCommand ?? (_myCommand =
new RelayCommand(_worker.RunWorkerAsync, CanMyCommand));
}
}
private bool CanMyCommand()
{
return true;
}
/// <summary>
/// Handlers
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 10; i++)
ConsumingMethod();
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Thread.Sleep(5000);
Messenger.Default.Send(new CloseAddDocumentWindow(String.Empty));
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
CurrentProgress = e.ProgressPercentage;
}
/// <summary>
/// Method
/// </summary>
private void ConsumingMethod()
{
CurrentProgress += _step;
}
}
代码隐藏:
Messenger.Default.Register<CloseAddDocumentWindow>(this, nm =>
{
if (nm.Sender == DataContext)
Close();
});
So, this
Messenger.Default.Send(new CloseAddDocumentWindow(String.Empty));
是问题所在。如您所见,该行关闭窗口。如果我评论该行,进度条效果很好。 10、20、30……100% 我明白了。但除此之外,进度条看起来像 10、20、30……90%,一些等待和窗口关闭!我尝试使用 Thread.Sleep(5000) 来给进度条一些时间来绘制。但即便如此也无济于事。那么,如果窗口立即关闭,我怎样才能看到最后的百分比变化呢?
对于任何未来的读者:
后台工作者的 DoWork
在新线程上执行,例如允许在不锁定 UI 的情况下进行工作。这RunWorkerCompleted
功能将在调用线程上为您运行,这意味着它返回到 UI 线程,并且此处完成的任何工作都可以锁定 UI。
ProgressBar 正在通过不同的线程进行更新,从而允许其更新。但一旦该值从 90 变为 100,UI 就会执行此“关闭”操作。当OP添加Sleep(5000)时;它位于 UI 线程 Completed 中,因此阻止 ProgressBar 显示完整的 100%。
解决方案是将睡眠从 Completed 移至 DoWork 循环,或者至少在循环之后,在发送关闭之前查看 ProgressBar 达到 100%。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)