Skip to main content
All docs
V24.2

DevExpress v24.2 Update — Your Feedback Matters

Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

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