Reputation: 4652
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
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
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