Back to Devexpress

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

windowsforms-403146-controls-and-libraries-spreadsheet-examples-customization-how-to-create-a-custom-progress-indicator-for-the-spreadsheet-control.md

latest11.8 KB
Original Source

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

  • May 19, 2021
  • 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.

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.

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.

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.

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.

csharp
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();
    }
}
vb
Imports System
Imports System.Threading
Imports DevExpress.XtraWaitForm
' ...

Partial Public Class WaitForm1
    Inherits WaitForm

    Private cancellationTokenSource As CancellationTokenSource

    Public Sub New()
        InitializeComponent()
        progressPanel1.AutoSize = True
    End Sub

    Public Overrides Sub SetCaption(ByVal caption As String)
        MyBase.SetCaption(caption)
        progressPanel1.Caption = caption
    End Sub

    Public Overrides Sub SetDescription(ByVal description As String)
        MyBase.SetDescription(description)
        progressPanel1.Description = description
    End Sub

    Public Overrides Sub ProcessCommand(ByVal cmd As System.Enum, ByVal arg As Object)
        MyBase.ProcessCommand(cmd, arg)
        Dim command As WaitFormCommand = CType(cmd, WaitFormCommand)
        If command = WaitFormCommand.SetCancellationTokenSource Then
            cancellationTokenSource = DirectCast(arg, CancellationTokenSource)
        End If
    End Sub

    Public Enum WaitFormCommand
        SetCancellationTokenSource
    End Enum

    Private Sub Cancel_Click(ByVal sender As Object, ByVal e As EventArgs) _ 
        Handles hyperlinkLabelControl1.Click
        cancellationTokenSource?.Cancel()
    End Sub
End Class

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.

csharp
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;
    }
}
vb
Imports System
Imports System.Threading
Imports DevExpress.Office.Services
Imports DevExpress.Office.Services.Implementation
Imports DevExpress.Services
' ...

Partial Public Class Form1
    Inherits DevExpress.XtraBars.Ribbon.RibbonForm
    Implements IProgressIndicationService

    Private cancellationTokenSource As CancellationTokenSource
    Private savedCancellationTokenProvider As ICancellationTokenProvider

    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))
        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)
    End Sub

    Private Sub IProgressIndicationService_End() Implements IProgressIndicationService.End
        ' Close the Wait Form.
        If splashScreenManager1.IsSplashFormVisible Then
            splashScreenManager1.CloseWaitForm()
        End If
        ' 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 Wait Form.
        splashScreenManager1.SetWaitFormDescription($"{currentProgress}%")
    End Sub

    Private Sub spreadsheetControl1_UnhandledException(ByVal sender As Object,
        ByVal e As DevExpress.XtraSpreadsheet.SpreadsheetUnhandledExceptionEventArgs) _
        Handles spreadsheetControl1.UnhandledException
        ' Handle OperationCanceledException.
        If TypeOf e.Exception Is OperationCanceledException Then
            e.Handled = True
        End If
    End Sub
End Class