Perform Time-Consuming Operation while Showing Busy Indicator
Environment
Product Version | 2019.3.917 |
Product | RadBusyIndicator for WPF |
Description
How to display a busy indicator while executing a heavy operation.
Solution
To perform the heavy operation without blocking the UI thread, you can create a BackgroundWorker and utilize its DoWork and RunWorkerCompleted events.
Example 1: Using the BackgroundWorker in the viewmodel
public class MainViewModel : ViewModelBase
{
private ObservableCollection<string> items;
private BackgroundWorker BackgroundWorker = new BackgroundWorker();
private bool isBusy;
public MainViewModel()
{
this.DoWorkCommand = new DelegateCommand(this.OnDoWorkExecuted);
this.BackgroundWorker.DoWork += BackgroundWorker_DoWork;
this.BackgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
this.BackgroundWorker.RunWorkerAsync();
}
public ICommand DoWorkCommand { get; private set; }
public bool IsBusy
{
get
{
return this.isBusy;
}
set
{
if (this.isBusy != value)
{
this.isBusy = value;
this.OnPropertyChanged(() => this.IsBusy);
}
}
}
public ObservableCollection<string> Items
{
get
{
return this.items;
}
set
{
if (this.items != value)
{
this.items = value;
this.OnPropertyChanged(() => this.Items);
}
}
}
private ObservableCollection<string> GetData()
{
return new ObservableCollection<string>()
{
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5"
};
}
private void OnDoWorkExecuted(object parameter)
{
this.BackgroundWorker.RunWorkerAsync();
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.IsBusy = false;
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
this.IsBusy = true;
Thread.Sleep(3000);
this.Items = GetData();
}
}
You can then bind your view to this viewmodel as demonstrated in Example 2.
Example 2: Defining and binding the RadBusyIndicator
<Grid>
<Grid.DataContext>
<local:MainViewModel />
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<telerik:RadBusyIndicator IsBusy="{Binding IsBusy}">
<telerik:RadListBox ItemsSource="{Binding Items}" />
</telerik:RadBusyIndicator>
<Button Content="Do Work" Command="{Binding DoWorkCommand}" Grid.Row="1" />
</Grid>