Skip to main content
All docs
V25.1
  • 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;
        }
    }