Reputation: 16690
I just recently began working with WPF and am trying to implement a ProgressBar but can't get it to do what I want.
All I want is for the UI to show the progress bar while a task is occurring, but it should not be visible otherwise.
This what I have in the xaml:
<ProgressBar x:Name="pbarTesting" HorizontalAlignment="Left" Height="37"
Margin="384,301,0,0" VerticalAlignment="Top" Width="264" IsHitTestVisible="True"
IsIndeterminate="True" Visibility="Collapsed"/>
And in the application I wrote:
progressBar.Visibility = Visibility.Visible;
doTimeConsumingStuff();
progressBar.Visibility = Visibility.Hidden;
However, when I get to the time consuming stuff, the progress bar never shows up. Can anyone tell me what I'm doing wrong?
Upvotes: 1
Views: 7321
Reputation: 283
Try adding these methods to your MainWindow class:
private void hideProgressBar ( )
{
this.Dispatcher.Invoke ( (Action) ( ( ) => {
progressBar.Visibility = Visibility.Hidden;
} ) );
}
private void showProgressBar ( )
{
this.Dispatcher.Invoke ( (Action) ( ( ) => {
progressBar.Visibility = Visibility.Visible;
} ) );
}
An updateProgress ( int progress )
method would look the same. Make the methods public
if the threads calling the progress bar updates are in a different class.
Upvotes: 2
Reputation: 786
WPF starts with only one thread which is called UI thread. UI doesn't update other than UI thread. When we do a long running operation in UI thread; Update of UI halts. So, when we need to update UI during a long running operation, we can start the long running operation in other thread than UI thread.
In the following example I started a long running operation in a backgroud thread. When operation finish it returns a value and I took it in UI thread.
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";
}
Upvotes: 4
Reputation: 61349
doTimeConsumingStuff
is locking the UI thread, so the visibility never has a chance to take effect.
You need to put that operation on a separate Thread
, with some sort of callback or event to then hide the progress bar.
Upvotes: 2