Skip to main content
All docs
V23.2

Create a Custom Progress Indicator for the Spreadsheet

  • 5 minutes to read

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.

Spreadsheet Progress Bar

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.

Example: Use a Splash Screen as a Custom Progress Indicator

The example below demonstrates how to use a custom splash screen instead of the default progress bar.

Spreadsheet - Custom Progress Indicator

View Example: Create a Custom Progress Indicator for the WPF Spreadsheet Control

Create a Custom Splash Screen

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();
    }
}

Implement the Progress Indication Service

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;
    }
}