AdamMc331
AdamMc331

Reputation: 16690

How to set the visibility of a ProgessBar in WPF?

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

Answers (3)

Richard Klassen
Richard Klassen

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

zaman
zaman

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

BradleyDotNET
BradleyDotNET

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

Related Questions