Skip to content

DevExpress-Examples/wpf-splash-screen-show-cancelable-wait-indicator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WPF Splash Screen - Show a Cancelable Wait Indicator

This example illustrates how to start a complex operation in a background thread and display its progress and status (Loading, Finishing, etc.) in the Splash Screen. This Splash Screen also contains the Close button that allows users to cancel the operation and close the Splash Screen.

image

Use SplashScreenManagerService to operate with this manager in an MVVM way.

Implementation Details

Add the SplashScreenManagerService to the MainView. Specify the required Splash Screen UI in the SplashScreenView and assign this view to the service's ViewTemplate:

<dxmvvm:Interaction.Behaviors>
    <dxmvvm:DispatcherService/>
    <dx:SplashScreenManagerService OwnerLockMode="WindowInputOnly"
                                   StartupLocation="CenterOwner">
        <dx:SplashScreenManagerService.ViewTemplate>
            <DataTemplate>
                <Views:SplashScreenView />
            </DataTemplate>
        </dx:SplashScreenManagerService.ViewTemplate>
        <dx:SplashScreenManagerService.SplashScreenWindowStyle>
            <Style TargetType="dx:SplashScreenWindow">
                <Setter Property="AllowAcrylic" Value="True" />
                <Setter Property="AllowsTransparency" Value="True" />
                <Setter Property="Background" Value="#B887A685" />
            </Style>
        </dx:SplashScreenManagerService.SplashScreenWindowStyle>
    </dx:SplashScreenManagerService>
</dxmvvm:Interaction.Behaviors>

When the Splash Screen is shown, this SplashScreenView's DataContext contains an instance of the DXSplashScreenViewModel (or its descendant) class. You can bind visual elements of the SplashScreenView to the Logo, Title, Progress, and Status properties from this class. When you change these settings in the SplashScreenManagerService.ViewModel object, SplashScreenView's elements reflect these changes.

The executed complex operation does not allow you to update the view model that is created in the main thread. To avoid this, create a DispatcherService that can update the Splash Screen's view model properties.

The main view model is a ViewModelBase class descendant. Use the approach from the Services in ViewModelBase descendants article to get access to the view services:

public ISplashScreenManagerService SplashScreenManagerService {
    get { return this.GetService<ISplashScreenManagerService>(); }
}

public IDispatcherService DispatcherService {
    get { return this.GetService<IDispatcherService>(); }
}

NOTE
Refer to the following help topics if you use other view model types:

The BackgroundWorker class allows you to execute a complex operation in a background thread. Set the WorkerSupportsCancellation property to true to cancel the operation on demand:

BackgroundWorker worker;

void RunBackgroundWorker() {
    worker = new BackgroundWorker();
    worker.DoWork += Worker_DoWork;
    worker.WorkerSupportsCancellation = true;
    worker.RunWorkerAsync();
}

private void Worker_DoWork(object sender, DoWorkEventArgs e) {
    int i = -1;
    while(++i < 100) {
        if(worker.CancellationPending) {
            e.Cancel = true;
            break;
        }
        UpdateSplashScreenContent(i);
        Thread.Sleep(200);
    }
    this.DispatcherService.Invoke(() => {
        this.SplashScreenManagerService.Close();
        worker.DoWork -= Worker_DoWork;
        worker = null;
    });
}

When a user clicks the "Start a complex operation" button, initialize properties in the SplashScreenManagerService.ViewModel and show the Splash Screen:

[Command(CanExecuteMethodName = "CanStart")]
public void Start() {
    if(this.SplashScreenManagerService != null) {
        this.SplashScreenManagerService.ViewModel = new DXSplashScreenViewModel();
        this.InitSplashScreenViewModel(this.SplashScreenManagerService.ViewModel);
        this.SplashScreenManagerService.Show();
        this.RunBackgroundWorker();
    }
}

In the InitSplashScreenViewModel define the Title, SubTitle, Progress, and other settings. Set the Tag property in the Splash Screen's view model to DelegateCommand that calls the CancelOperation method from the main view model:

void InitSplashScreenViewModel(DXSplashScreenViewModel vm) {
    vm.Title = "SOME BACKGROUND WORK";
    vm.SubTitle = "This can take some time";
    vm.Logo = new Uri("pack://application:,,,/logo.png");
    vm.IsIndeterminate = false;
    vm.Tag = new DelegateCommand(CancelOperation, CanCancelOperation);
}

public bool CanCancelOperation() { return worker != null && worker.IsBusy; }

public void CancelOperation() {
    if(worker != null && worker.IsBusy)
        worker.CancelAsync();
}

In the Splash Screen's view, bind the close button's Command property to the View Model's Tag property:

...
<dx:SimpleButton Margin="20"
                 HorizontalAlignment="Right"
                 VerticalAlignment="Top"
                 Command="{Binding Tag}"
                 Glyph="{dx:DXImage GrayScaleImages/Edit/Delete_16x16.png}"
                 ToolTip="Cancel and Close" />
...

To update the Splash Screen during a complex operation, set the Progress and State properties in the SplashScreenManagerService.ViewModel object to the required values. To do this in the main thread, use the DispatcherService's Invoke method:

void UpdateSplashScreenContent(int progressValue) {
    var state = string.Empty;
    state = progressValue < 20 ? "Starting..." : progressValue < 70 ? "Loading data.." : "Finishing";
    this.DispatcherService.Invoke(() => {
        this.SplashScreenManagerService.ViewModel.Progress = progressValue;
        this.SplashScreenManagerService.ViewModel.Status = $"({progressValue} %) - {state}";
    });
}

Files to Review

Documentation

More Examples

About

Start a complex operation in a background thread and display its progress and status in the Splash Screen.

Topics

Resources

License

Stars

Watchers

Forks