John Threepwood
John Threepwood

Reputation: 16143

How to call a background thread properly in a work in progress dialog?

The main window of our application opens a work in progress dialog which should call a background thread. The dialog should appear until the thread is finished:

var dialog = new WorkInProgressDialog();
dialog = ShowDialg;

The problem now is where/how to call the thread in WorkInProgressDialog constructor? If it is called in the constructor, the dialog will not be visible until the thread is finished.

Also the dialog should be automatically closed after the thread is completed.

Upvotes: 1

Views: 91

Answers (1)

Gary Wright
Gary Wright

Reputation: 2469

Here is a sample that will hopefully help you. Some simple markup for the WorkInProgressDialog:

<Window x:Class="WorkInProgressExample.WorkInProgressDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WorkInProgressDialog" Height="100" Width="300" WindowStyle="None" 
    ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
    <Border BorderThickness="3" CornerRadius="5" BorderBrush="Black" Padding="10">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>            

            <TextBlock Grid.Row="1" Name="WorkProgressTextBlock">Work in progress...</TextBlock>
            <ProgressBar Grid.Row="2" Height="30" Name="WorkProgressBar"></ProgressBar>
        </Grid>
    </Border>
</Window>

Then in the code behind:

private bool _closeAuthorised = false;

public WorkInProgressDialog()
{
    InitializeComponent();

    WorkProgressBar.Maximum = 10;
    WorkProgressBar.Minimum = 0;

    Task.Factory.StartNew(() =>
    {
        // Do whatever processing you need to here
        for (int i = 0; i < 10; i++)
        {
            // Any updates to the UI need to be done on the UI thread
            this.Dispatcher.Invoke((Action)(() =>
            {
                WorkProgressBar.Value = i;
            }));

            Thread.Sleep(1000);
        }

        // Set the DialogResult and hence close, also on the UI thread
        this.Dispatcher.Invoke((Action)(() =>
        {
            _closeAuthorised = true;
            this.DialogResult = true;
        }));

    });
}

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    // If the user uses ALT+F4 to try andclose the loading dialog, this will cancel it
    if (!_closeAuthorised)
        e.Cancel = true;
    base.OnClosing(e);
}

Then where you want to use it:

var dialog = new WorkInProgressDialog();
bool? result = dialog.ShowDialog();

Upvotes: 1

Related Questions