我刚刚开始使用WPF并且正在尝试实现ProgressBar,但却无法让它按照我的意愿去做。
我想要的只是UI在任务发生时显示进度条,但不应该以其他方式显示。
这就是我在xaml中所拥有的:
<ProgressBar x:Name="pbarTesting" HorizontalAlignment="Left" Height="37"
Margin="384,301,0,0" VerticalAlignment="Top" Width="264" IsHitTestVisible="True"
IsIndeterminate="True" Visibility="Collapsed"/>
在我写的应用程序中:
progressBar.Visibility = Visibility.Visible;
doTimeConsumingStuff();
progressBar.Visibility = Visibility.Hidden;
然而,当我得到耗时的东西时,进度条永远不会显示出来。谁能告诉我我做错了什么?
答案 0 :(得分:4)
WPF只从一个称为UI线程的线程开始。 UI不会更新UI线程以外的其他内容。当我们在UI线程中进行长时间运行时; UI停止更新。因此,当我们需要在长时间运行的操作期间更新UI时,我们可以在除UI线程之外的其他线程中启动长时间运行的操作。
在以下示例中,我在backgroud线程中启动了长时间运行的操作。当操作完成时,它返回一个值,我把它放在UI线程中。
private void MethodThatWillCallComObject()
{
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
//this will call in background thread
return this.MethodThatTakesTimeToReturn();
}).ContinueWith(t =>
{
//t.Result is the return value and MessageBox will show in ui thread
MessageBox.Show(t.Result);
}, System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());
}
private string MethodThatTakesTimeToReturn()
{
System.Threading.Thread.Sleep(5000);
return "end of 5 seconds";
}
答案 1 :(得分:2)
doTimeConsumingStuff
锁定了UI线程,因此可见性永远不会生效。
您需要将该操作放在单独的Thread
上,并使用某种回调或事件来隐藏进度条。
答案 2 :(得分:2)
尝试将这些方法添加到MainWindow类中:
private void hideProgressBar ( )
{
this.Dispatcher.Invoke ( (Action) ( ( ) => {
progressBar.Visibility = Visibility.Hidden;
} ) );
}
private void showProgressBar ( )
{
this.Dispatcher.Invoke ( (Action) ( ( ) => {
progressBar.Visibility = Visibility.Visible;
} ) );
}
updateProgress ( int progress )
方法看起来一样。如果调用进度条更新的线程在不同的类中,则使方法public
。