Skip to main content
All docs
V23.2

How to: Create a Custom Progress Indicator for the Spreadsheet Control

  • 5 minutes to read

The WinForms Spreadsheet control ships with a predefined progress bar that indicates the progress of lengthy operations (file load/save operations and export to PDF/HTML). Add a status bar to the Spreadsheet control to display the progress bar. See this topic for details: Get Started with the WinForms Spreadsheet Control.

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 Wait Form as a Custom Progress Indicator

The example below demonstrates how to use a DevExpress Wait Form instead of the default progress bar.

Spreadsheet - Custom Progress Indicator

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

Create a Wait Form

Drop the SplashScreenManager component onto your form. Select this component in the Visual Studio tray and click Add Wait Form in the SplashScreenManager Tasks menu.

Add Wait Form

The Splash Screen Manager creates a new Wait Form within your project. Add the HyperlinkLabelControl component to the form and set the control’s Text property to Cancel.

Wait Form Design

Change the Wait Form‘s code as shown below to define the caption and description of the form’s built-in progress panel. A custom SetCancellationTokenSource command specifies the CancellationTokenSource object used to cancel the operation when a user clicks Cancel.

using System;
using System.Threading;
using DevExpress.XtraWaitForm;
// ...

public partial class WaitForm1 : WaitForm {
    CancellationTokenSource cancellationTokenSource;

    public WaitForm1() {
        InitializeComponent();
        progressPanel1.AutoSize = true;
    }

    public override void SetCaption(string caption) {
        base.SetCaption(caption);
        progressPanel1.Caption = caption;
    }

    public override void SetDescription(string description) {
        base.SetDescription(description);
        progressPanel1.Description = description;
    }

    public enum WaitFormCommand {
        SetCancellationTokenSource
    }

    public override void ProcessCommand(Enum cmd, object arg) {
        base.ProcessCommand(cmd, arg);
        WaitFormCommand command = (WaitFormCommand)cmd;
        if (command == WaitFormCommand.SetCancellationTokenSource)
            cancellationTokenSource = (CancellationTokenSource)arg;
    }

    void Cancel_Click(object sender, EventArgs 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.

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.Office.Services;
using DevExpress.Office.Services.Implementation;
using DevExpress.Services;
// ...

public partial class Form1 : DevExpress.XtraBars.Ribbon.RibbonForm, IProgressIndicationService
{
    CancellationTokenSource cancellationTokenSource;
    ICancellationTokenProvider savedCancellationTokenProvider;

    public Form1() {
        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));
        splashScreenManager1.ShowWaitForm();
        // Display the name of the running operation in the Wait Form. 
        splashScreenManager1.SetWaitFormCaption(displayName);
        // Display the progress of the running operation in the Wait Form.
        splashScreenManager1.SetWaitFormDescription($"{currentProgress}%");
        // Send a command to the Wait Form
        // to specify the CancellationTokenSource object
        // used to generate cancellation tokens for the task cancellation.
        splashScreenManager1.SendCommand(WaitForm1.WaitFormCommand.SetCancellationTokenSource, 
            cancellationTokenSource);
    }

    void IProgressIndicationService.End() {
        // Close the Wait Form.
        if (splashScreenManager1.IsSplashFormVisible)
            splashScreenManager1.CloseWaitForm();
        // 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 Wait Form.
        splashScreenManager1.SetWaitFormDescription($"{currentProgress}%");
    }

    void spreadsheetControl1_UnhandledException(object sender, 
        DevExpress.XtraSpreadsheet.SpreadsheetUnhandledExceptionEventArgs e) {
        // Handle OperationCanceledException.
        if (e.Exception is OperationCanceledException)
            e.Handled = true;
    }
}