Akrem
Akrem

Reputation: 4652

How to force BusyIndicator?

I use Extended WPF Toolkit BusyIndicator

My Xaml

<extToolkit:BusyIndicator Name="wait" IsBusy="False" Cursor="Wait" Grid.ColumnSpan="3" Margin="10,10,10,10"/>

My code:

private void esp_Click(object sender, RoutedEventArgs e)
{
    wait.IsBusy = true;

    // My work here make some time to finish

    wait.IsBusy = false;
}

But it never be showed, I try to make MessageBox in the end of the function the BusyIndicator be showed after the MessageBox,

I tried

wait.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send,
                       (Action)delegate
{
    wait.IsBusy = true;
});

But I got nothing!!! Where’s the problem here I can’t resolved it?

I found a similar question but I don't have the same problem the indicator showing up but after the complete of the function.

Upvotes: 3

Views: 3505

Answers (2)

Rumplin
Rumplin

Reputation: 2768

You could do it with INotifyPropertyChanged:

<extToolkit:BusyIndicator Name="wait" IsBusy="{Binding IsBusy}" Cursor="Wait" Grid.ColumnSpan="3" Margin="10,10,10,10"/>

and the C#:

    /// <summary>
    /// The <see cref="IsBusy" /> property's name.
    /// </summary>
    public const string IsBusyPropertyName = "IsBusy";
    private bool _isBusy = false;

    public bool IsBusy
    {
        get
        {
            return _isBusy;
        }

        set
        {
            if (_isBusy != value)
            {
                _isBusy = value;
                RaisePropertyChanged(IsBusyPropertyName);                   
            }
        }
    }

Upvotes: 2

maciejkow
maciejkow

Reputation: 6453

The problem is that you're performing all the work in dispatcher's thread (I assume that esp_Click is an event handler). This effectively means that while performing long tasks, UI is not being updated.

You need to perform work in separate thread - either create a new thread, use thread pool or create a task. Set IsBusy to true before starting and to false after completing your work. You'll need to use Dispatcher.BeginInvoke/Invoke when updating wait.IsBusy from another thread.

Sample code:

private void LongRunningTask() 
{
   // your long running code

   // after you complete:
   Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send,
                           (Action)delegate
    {
        wait.IsBusy = false;
    }); 
}

private void esp_Click(object sender, RoutedEventArgs e)
{
   wait.IsBusy = true; // either here, or in your long running task - but then remember to use dispatcher

   var thread = new Thread(LongRunningTask);
   thread.Start();

   // OR

   ThreadPool.QueueUserWorkItem(state => LongRunningState());

   // OR, in .NET 4.0

   Task.Factory.StartNew(LongRunningTask);
}

Note that neither of this solutions handles exceptions - you'll have to add error handling yourself (or use task continuations in case of last sample).

Upvotes: 6

Related Questions