.NET Core TaskDialog
Tags: codenewbie, dotnet, csharp
Published: 2023-04-23 16:26:13

When an application requires a message to be display or to ask a user questions the common method is to use a [MessageBox](https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.messagebox?view=windowsdesktop-6.0). 

Beginning with .NET Core 5 there is a new way to interact with users which is what this article is about using [TaskDialog class](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.taskdialog?view=windowsdesktop-7.0).

{% cta https://github.com/karenpayneoregon/task-dialog-csharp %} GitHub repository {% endcta %}

The original code was written using .NET Core 5 and as of this article all source code is .NET Core 7.

A standard `message box` with its many `overloads` for `Show` method is fine for simply displaying and asking for input (without a input/textbox) while the TaskDialog provides more flexibilities. With these flexibilities comes more code which can be placed into a separate class in a project or better, place code into a separate class project. To use the class project, add a reference to a project or create a NuGet local package and install the package in any project.

Below find common examples for using a TaskDialog in a Windows Form and WPF projects. And note that there are many more methods to explore in the class project WindowsFormsLibrary.

WPF Example launch interface

![WPF example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4p3lgmvjo79xvnm1zpj9.png)

Windows Forms Example launch interface

![Windows forms launch interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7oud8y27ucs15cw49ovo.png)

- Display a dialog to ask a question with radio buttons
- A dialog with a hyperlink to open a web site
- Ask a question with the default button set
- Ask a question with a defined timeout and custom button text
- Ask a question with defined icon and button text

![TaskDialog examples](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wlzg2ze1doladf8fgcz.png)

:bulb: There are 25 plus examples to learn `TaskDialog` from, take time to traverse the code rather than simply running the code samples to get a grasp of what is possible.

## Front end projects

There are two frontend projects, one Windows Forms and one WPF. The Windows Forms project has more code samples but the WPF project is capable of the same code as found in the Windows Forms project. Why? Generally speaking there are more developers using Windows Forms than WPF.

A third project, AutoCloseNotTaskDialog is a clean way to have a auto closing MessageBox prior to .NET Core 5. This project has not been updated to .NET Core 7.

## How to use

Best way to use the code is to take the class project WindowsFormsLibrary, place it in a Visual Studio solution then build the solution.

For ease of use, redirect the build output to a library folder e.g. C:\DotNet\Libraries then when needed in a frontend project, add a reference to the dll. Alternate is to create a local NuGet package, add the local NuGet folder to NuGet package manager under Visual Studio and when needed install the package to a project.

Here the author (Karen) uses C:\Dotnetland\NuGet for local packages


![Local Nuget package location](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9bnr8qef26h44abhz1qo.png)

Here is an great example were TaskDialog provides an easy way to present a user with a question along with an option to not show the dialog again.

## Do not show again example

Displaying a message box with an option to now show again as shown below is not possible with a MessageBox.


![do not show again dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1i8t2xcscby2b8w83ny9.png)

Firs thing which is needed is a place to remember do not show again settings. Here a json file is used.

```json
{
  "ShowAgain": true,
  "Heading": "Are you sure you want to stop?",
  "Text": "Stopping the operation might leave your database in a corrupted state.",
  "Caption": "Confirmation",
  "VerificationText": "Do not show again"
}
```

Using the following class to provide dialog settings where `ShowAgain` is set from the result of the following method.

```csharp
/// <summary>
/// Display a dialog with option to not display again where thier choice
/// is stored in appsettings.json
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DoNotShowAgainButton_Click(object sender, RoutedEventArgs e)
{
    var settings = SettingOperations.GetSetting;

    if (!settings.ShowAgain) return;
    ShowAgainOptions options = new ShowAgainOptions
    {
        Heading = settings.Heading,
        Text = settings.Text,
        Caption = settings.Caption,
        Icon = _DatabaseIcon,
        VerificationText = settings.VerificationText,
        IntPtr = _intPtr
    };

    (NoShowResult DialogResult, bool ShowAgain) result = Dialogs.DoNotShowAgain(options);
    ShowAgainCheckBox.IsChecked = result.ShowAgain;

}
```

Usage shown for WPF (a Windows Form version is also available)

```csharp
private void DoNotShowAgainButton_Click(object sender, RoutedEventArgs e)
{
    var settings = SettingOperations.GetSetting;

    if (!settings.ShowAgain) return;
    ShowAgainOptions options = new ShowAgainOptions
    {
        Heading = settings.Heading,
        Text = settings.Text,
        Caption = settings.Caption,
        Icon = _DatabaseIcon,
        VerificationText = settings.VerificationText,
        IntPtr = _intPtr
    };

    (NoShowResult DialogResult, bool ShowAgain) result = Dialogs.DoNotShowAgain(options);
    ShowAgainCheckBox.IsChecked = result.ShowAgain;

}
```
## With a progress bar

Something else that before TaskDialog a developer would need to create a form and code it to present a progress bar with cancellation option which takes a good deal of code.


![progress bar example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5peiatbqpsiiadix78q6.png)

```csharp
public static void AutoClosingTaskDialog(Icon Icon)
{

    const string textFormat = "Closing in {0} seconds...";
    var remainingTenthSeconds = 30;

    TaskDialogButton continueButton = new ("Just do it");
    TaskDialogButton cancelButton = TaskDialogButton.Cancel;
    
    TaskDialogPage page = new ()
    {
        Heading = "Continuing with next process...",
        Text = string.Format(textFormat, (remainingTenthSeconds + 9) / 10),
        Icon = new TaskDialogIcon(Icon),
        ProgressBar = new TaskDialogProgressBar() { State = TaskDialogProgressBarState.Paused },
        Buttons = new TaskDialogButtonCollection() { continueButton, cancelButton }, 
        Caption = "Auto-close"
    };

    using Timer timer = new ()
    {
        Enabled = true,
        Interval = 100
    };

    timer.Tick += (_, _) =>
    {
        remainingTenthSeconds -= 1;

        if (remainingTenthSeconds > 0)
        {
            page.Text = string.Format(textFormat, (remainingTenthSeconds + 9) / 10);
            page.ProgressBar.Value = 100 - remainingTenthSeconds * 2;
        }
        else
        {
            timer.Enabled = false;

            if (continueButton.BoundPage is not null)
            {
                continueButton.PerformClick();
            }
            
        }
    };

    TaskDialogButton result = TaskDialog.ShowDialog(page);

    ContinueOperation?.Invoke(result == continueButton);

}
```
## More examples!!!

In the [GitHub repository](https://github.com/karenpayneoregon/task-dialog-csharp) there are a great deal of examples for both Windows Forms and WPF to checkout including using delegates and events with TaskDialog.

## Source code

Clone the following [GitHub repository](https://github.com/karenpayneoregon/task-dialog-csharp)



##  How to use in your project

Once cloned the GitHub repository copy the project **WindowsFormsLibrary** into a Visual Studio Solution, add the reference to the library in your project. 

> **Note**
> There are a few classes which can be removed for personal use like PowerShellOperations.cs and MachineComputerInformation.cs which only needed to run the provided code samlples.


![project reference dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgy1mplnvw5ebh14rkny.png)

In a form or class, add a reference e.g.

```csharp
using WindowsFormsLibrary.Classes;
using WindowsFormsLibrary.LanguageExtensions;
```