wpf-403147-controls-and-libraries-spreadsheet-getting-started-create-a-custom-progress-indicator-for-the-spreadsheet.md
The WPF Spreadsheet control ships with a predefined progress bar that indicates the progress of lengthy operations (file load/save operations and export to PDF/HTML). To display the progress bar, add a status bar to the Spreadsheet control. See this topic for more information: Create a Simple Spreadsheet Application.
You can use an IProgressIndicationService service to create a custom progress indicator. Create a class that implements this interface and pass a class instance to the SpreadsheetControl.ReplaceService method to replace the default progress indication service with your own service.
The example below demonstrates how to use a custom splash screen instead of the default progress bar.
View Example: Create a Custom Progress Indicator for the WPF Spreadsheet Control
Inherit a custom splash screen from the SplashScreenWindow class. Add the following elements to the splash screen:
TextBox — displays the name of the operation.
ProgressBar — indicates the progress of the operation.
TextBox — displays the Cancel hyperlink that allows users to cancel the operation.
<dx:SplashScreenWindow x:Class="WpfSpreadsheetProgressSample.CustomSplashScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxt="http://schemas.devexpress.com/winfx/2008/xaml/core/themekeys"
xmlns:mvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
BorderBrush="{DynamicResource {dxt:BrushesThemeKey ResourceKey=PanelBorder}}"
BorderThickness="1"
AllowTheming="True"
Height="120"
Width="300"
DataContext="{x:Static mvvm:DXSplashScreenViewModel.DesignTimeData}">
<dx:BackgroundPanel>
<StackPanel VerticalAlignment="Center" Margin="16">
<TextBlock Text="{Binding Title}"
FontSize="16"
HorizontalAlignment="Left"
Margin="0,0,0,8"/>
<ProgressBar IsIndeterminate="False"
Height="20"
Width="240"
Value="{Binding Progress}"/>
<TextBlock Text="Cancel"
HorizontalAlignment="Right"
Margin="0,8,0,0"
Foreground="#FF1686F5"
TextDecorations="Underline"
Cursor="Hand"
MouseLeftButtonUp="Cancel_Click" />
</StackPanel>
</dx:BackgroundPanel>
</dx:SplashScreenWindow>
A CancellationTokenSource object is passed to the CustomSplashScreen constructor to cancel the operation when a user clicks Cancel.
using System;
using System.Threading;
using System.Windows.Input;
using DevExpress.Xpf.Core;
// ...
public partial class CustomSplashScreen : SplashScreenWindow {
readonly CancellationTokenSource cancellationTokenSource;
public CustomSplashScreen(CancellationTokenSource cancellationTokenSource) {
this.cancellationTokenSource = cancellationTokenSource;
InitializeComponent();
}
private void Cancel_Click(object sender, MouseButtonEventArgs e) {
cancellationTokenSource?.Cancel();
}
}
Imports System
Imports System.Threading
Imports DevExpress.Xpf.Core
' ...
Partial Public Class CustomSplashScreen
Inherits SplashScreenWindow
Private ReadOnly cancellationTokenSource As CancellationTokenSource
Public Sub New(ByVal cancellationTokenSource As CancellationTokenSource)
Me.cancellationTokenSource = cancellationTokenSource
InitializeComponent()
End Sub
Private Sub Cancel_Click(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
cancellationTokenSource?.Cancel()
End Sub
End Class
Implement the IProgressIndicationService interface methods as shown below and use the SpreadsheetControl.ReplaceService method to substitute the default service with a custom service.
The SplashScreenManager.Create method allows you to create a CustomSplashScreen instance. Pass a DXSplashScreenViewModel object to the method to specify splash screen content.
Use the SpreadsheetControl.UnhandledException event to handle an OperationCanceledException exception that is thrown when a user cancels the operation.
using System;
using System.Threading;
using DevExpress.Mvvm;
using DevExpress.Office.Services;
using DevExpress.Office.Services.Implementation;
using DevExpress.Services;
using DevExpress.Xpf.Core;
// ...
public partial class MainWindow : ThemedWindow, IProgressIndicationService {
CancellationTokenSource cancellationTokenSource;
ICancellationTokenProvider savedCancellationTokenProvider;
SplashScreenManager splashScreenManager;
public MainWindow() {
InitializeComponent();
// Replace the default progress indication service
// with a custom service.
spreadsheetControl1.ReplaceService<IProgressIndicationService>(this);
}
void IProgressIndicationService.Begin(string displayName, int minProgress,
int maxProgress, int currentProgress) {
cancellationTokenSource = new CancellationTokenSource();
// Register a new CancellationTokenProvider instance
// to process cancellation requests. Save the reference
// to the previously registered service.
savedCancellationTokenProvider = spreadsheetControl1.ReplaceService<ICancellationTokenProvider>(
new CancellationTokenProvider(cancellationTokenSource.Token));
// Create a CustomSplashScreen instance.
// Display the name and progress of the running operation
// in the splash screen.
splashScreenManager = SplashScreenManager.Create(() =>
new CustomSplashScreen(cancellationTokenSource),
new DXSplashScreenViewModel
{
Title = displayName,
Progress = currentProgress
});
// Display the splash screen.
splashScreenManager.Show();
}
void IProgressIndicationService.End() {
// Close the splash screen.
splashScreenManager?.Close();
splashScreenManager = null;
// Restore previous CancellationTokenProvider.
spreadsheetControl1.ReplaceService(savedCancellationTokenProvider);
spreadsheetControl1.UpdateCommandUI();
// Dispose the CancellationTokenSource object.
cancellationTokenSource?.Dispose();
cancellationTokenSource = null;
}
void IProgressIndicationService.SetProgress(int currentProgress) {
// Display the progress of the running operation in the splash screen.
splashScreenManager.ViewModel.Progress = currentProgress;
}
void spreadsheetControl1_UnhandledException(object sender,
DevExpress.XtraSpreadsheet.SpreadsheetUnhandledExceptionEventArgs e) {
// Handle OperationCanceledException.
if (e.Exception is OperationCanceledException)
e.Handled = true;
}
}
Imports System
Imports System.Threading
Imports DevExpress.Mvvm
Imports DevExpress.Office.Services
Imports DevExpress.Office.Services.Implementation
Imports DevExpress.Services
Imports DevExpress.Xpf.Core
' ...
Partial Public Class MainWindow
Inherits ThemedWindow
Implements IProgressIndicationService
Private cancellationTokenSource As CancellationTokenSource
Private savedCancellationTokenProvider As ICancellationTokenProvider
Private splashScreenManager As SplashScreenManager
Public Sub New()
InitializeComponent()
' Replace the default progress indication service
' with a custom service.
spreadsheetControl1.ReplaceService(Of IProgressIndicationService)(Me)
End Sub
Private Sub IProgressIndicationService_Begin(ByVal displayName As String,
ByVal minProgress As Integer,
ByVal maxProgress As Integer,
ByVal currentProgress As Integer) _
Implements IProgressIndicationService.Begin
cancellationTokenSource = New CancellationTokenSource()
' Register a new CancellationTokenProvider instance
' to process cancellation requests. Save the reference
' to the previously registered service.
savedCancellationTokenProvider = spreadsheetControl1.ReplaceService(Of ICancellationTokenProvider)(
New CancellationTokenProvider(cancellationTokenSource.Token))
' Create a CustomSplashScreen instance.
' Display the name and progress of the running operation
' in the splash screen.
splashScreenManager = SplashScreenManager.Create(
Function() New CustomSplashScreen(cancellationTokenSource),
New DXSplashScreenViewModel With {
.Title = displayName,
.Progress = currentProgress
})
' Display the splash screen.
splashScreenManager.Show()
End Sub
Private Sub IProgressIndicationService_End() _
Implements IProgressIndicationService.End
' Close the splash screen.
splashScreenManager?.Close()
splashScreenManager = Nothing
' Restore previous CancellationTokenProvider.
spreadsheetControl1.ReplaceService(savedCancellationTokenProvider)
spreadsheetControl1.UpdateCommandUI()
' Dispose the CancellationTokenSource object.
cancellationTokenSource?.Dispose()
cancellationTokenSource = Nothing
End Sub
Private Sub IProgressIndicationService_SetProgress(ByVal currentProgress As Integer) _
Implements IProgressIndicationService.SetProgress
' Display the progress of the running operation in the splash screen.
splashScreenManager.ViewModel.Progress = currentProgress
End Sub
Private Sub spreadsheetControl1_UnhandledException(ByVal sender As Object,
ByVal e As DevExpress.XtraSpreadsheet.SpreadsheetUnhandledExceptionEventArgs)
' Handle OperationCanceledException.
If TypeOf e.Exception Is OperationCanceledException Then
e.Handled = True
End If
End Sub
End Class