Windows Vista and 7 have provided us with new functionality and new common controls to take advantage of. One control in particular to consider for your next application is the Task Dialog. It is easiest to think of Task Dialog as a Message Box on steroids. No doubt you have had to develop your own custom dialogs in order to perform an action that could have been supported by a customized message box? Task Dialogs perform this function with ease in your .NET apps, via the Windows API Code Pack.
Anatomy of a Task Dialog
Task Dialogs are divided into 11 areas. I will give a quick overview of all the sections, and then go into more depth for each section. By the end of this article, you should be able to build your own Task Dialogs without any problems.
The image above displays the various areas of a task dialog you can customize. I will go into more detail of all these areas, and how you can mix and match options. A task dialog is divided into the following sections:
- Title bar
- Instruction Text
- Collapsed Text
- Collapse Toggle
- Progress Bar
- Standard Buttons
- Footer Checkbox
- Footer Text
Getting started with the task dialog is easy. First, you need to download the Windows API Code Pack. The Windows API Code Pack provides an interface for .NET developers to take advantage of these features, without having to play in unmanaged code. You can also check out my overview of the Windows API Code Pack.
Unfortunately you'll need to compile the code pack from source - there's currently no binaries available, but it's straightforward following the instructions on the site. Once you have successfully compiled the code pack, you need to reference Microsoft.WindowsAPICodePack.dll for any applications you would like to use Task Dialogs in.
Hello Task Dialog
Now you can get started with some code! Here is the source needed to load a basic task dialog, and show it to the user.
TaskDialog dialog = new TaskDialog(); dialog.Text = "Hello Task Dialog"; dialog.Caption = "Hello Task Dialog"; dialog.Show();
Four lines of code to display a simple task dialog. There is not too much to explain in this example. We create a new TaskDialog object, and assign values to its Text and Caption properties. Finally, we Show the dialog to the user. If everything worked as planned, your Task Dialog should look like this:
A Simple Task Dialog
The “Hello Task Dialog” is about as simple as we can get. However, it is missing several elements that we would typically want to use in our task dialogs. For our simple task dialog, we will want to set up a few standard elements.
Referencing the anatomy photo above, we will be focusing on the title bar, instruction text, icon, and text properties. The following code snippet builds a basic Task Dialog
TaskDialog dialog = new TaskDialog(); dialog.Caption = "Application Error"; dialog.InstructionText = "CRASH AND BURN!"; dialog.Text = "The application has performed an illegal action. This action has been logged and reported."; dialog.Icon = TaskDialogStandardIcon.Error; dialog.Cancelable = false; dialog.Show();
The above code produces the following output:
If you are a native WinForms developer, you are going to recognize the Caption property. If you are not, this is the property that changes the text of the title bar. InstructionText gives the user direction as to the purpose of the dialog. This text is larger, and a different color from standard text. Text is an area for you to provide more information to the user. Icon can be one of four “standard” icons (the example above demonstrates the Error icon. This property is an instance of the TaskDialogStandardIcon enumeration. This enumeration has five values:
You might be thinking “This example is nothing more than a traditional Message Box,” and you would be right. Next we are going to look at how to expand the functionality of this task dialog to suit our various needs.
Task Dialogs give us the ability to give our users a lot of information. However, there might be information we want to hide by default. This information could be a stack trace, user details, or anything. Here is how you would define a collapsible section:
dialog.DetailsExpanded = false; dialog.DetailsCollapsedLabel = "Show Expanded Text"; dialog.DetailsExpandedLabel = "Hide Expanded Text"; dialog.DetailsExpandedText = @"### Start of Expanded Text ###" + Environment.NewLine + "" + Environment.NewLine + "### End of Expanded Text ###";
Let us walk through the code. DetailsExpanded tells the collapsed section to either start collapsed or expanded. By default, this value is false. The only required field for displaying a collapsible section is DetailsExpandedText. By setting this value to something, the task dialog will automatically render the toggle button. DetailsCollapsedLabel and DetailsExpandedLabel allow you to override the default labels, “See Details” and “Hide Details”.
Collapsible sections also allow you to put the DetailsExpandedText text in two areas, the content area and the footer.
The area can be trigger by inserting setting the ExpansionMode property to one of values:
Here is an example of the text in both areas:
Some actions on your task dialog might require the use of a progress bar. This can be easily achieved by instantiating a new instance of the ProgressBar property.
int minValue = 0; int maxValue = 100; int currentValue = 20; dialog.ProgressBar = new TaskDialogProgressBar(minValue, maxValue, currentValue);
The value of the progress bar can be changed by changing the ProgressBar.Value property. Additionally, we can set the ProgressBar.State property, which is an enumeration with 4 values.
- Error – turns the progress bar Red, designating that progress bar has encountered an error.
- Marquee – moves the highlighted part of the progress bar from left to the right repeatedly.
- None – sets the progress bar to default functionality.
- Paused – turns the highlighted part of the progress bar yellow, designating that the progress bar is in a paused state.
Standard controls are the meat of a task dialog, and the primary item that makes Task Dialogs more than a Message Box.
A command link is a button that allows the user to perform a function. This code is used to create command links:
TaskDialogCommandLink commandLink_Send = new TaskDialogCommandLink("buttonSendFeedback", "Send Feedback", "Please send feedback to the team."); TaskDialogCommandLink commandLink_Ignore = new TaskDialogCommandLink("buttonIgnore", "Ignore", "Please ignore this error."); dialog.Controls.Add(commandLink_Send); dialog.Controls.Add(commandLink_Ignore);
Here is an example of the produced output:
One thing you might notice is that after adding command links to our task dialog, we have lost the functionality of the original “OK” button. This is done as a convenience, and can easily be added back in, which I will cover in the next section, “Buttons”.
Command links do not do much unless you add a event handler for the Click event.
commandLink_Send.Click += new EventHandler(commandLink_Send_Click); commandLink_Ignore.Click += new EventHandler(commandLink_Ignore_Click);
Adding radio buttons to the task dialog is a similar to adding a command link.
TaskDialogRadioButton radioYes = new TaskDialogRadioButton("radioYes", "Yes, submit a feedback report."); TaskDialogRadioButton radioNo = new TaskDialogRadioButton("radioNo", "No, no feedback report needed."); dialog.Controls.Add(radioYes); dialog.Controls.Add(radioNo);
For all of our examples, we have been given the default “OK” button. Task Dialogs give us the option of adding as few or as many standard buttons as we want. Out of the box, we have the following buttons:
In order to select a standard button by setting the StandardButtons property.
dialog.StandardButtons = TaskDialogStandardButtons.Yes | TaskDialogStandardButtons.No; TaskDialogResult taskDialogResult = dialog.Show();
This example shows how we can perform a logical OR of two (or more) buttons to display on the dialog. When we Show the dialog, it will return a TaskDialogResult mapping to the types of buttons available.
The line of code above will produce this result:
Sometimes “Yes” and “No” might not be enough, and we would want to create our own custom buttons. In order to do this, we need to create a TaskDialogButton object.
TaskDialogButton customButtonYes = new TaskDialogButton("customButtonYes", "Yes, submit a feedback report."); TaskDialogButton customButtonNo = new TaskDialogButton("customButtonNo", "No, no feedback report needed."); customButtonYes.Click += new EventHandler(customButtonYes_Click); customButtonNo.Click += new EventHandler(customButtonNo_Click); dialog.Controls.Add(customButtonYes); dialog.Controls.Add(customButtonNo); TaskDialogResult taskDialogResult = dialog.Show();
Doing this will add the custom buttons in place of standard buttons. The only drawback is that you will need to handle your own click events. Here is what custom buttons look like in action:
The footer is last section of the Task Dialog we have to explore. This section can be used to give users important information that would normally not work anywhere else on the task dialog. Also, we can give users a check box option (in case you want to provide a “do not show this again” option or something similar).
dialog.FooterIcon = TaskDialogStandardIcon.Error; dialog.FooterText = "Your application crashed because a developer forgot to write a unit test."; dialog.FooterCheckBoxText = "Perform this action every time."; dialog.FooterCheckBoxChecked = true;
FooterIcon uses the same standard icons we used in the simple task dialog example, and it is displayed next to the FooterText. By setting a value for FooterCheckBoxText, a check box will be added to footer (next to the standard button). You can optionally set the check box to by setting the FooterCheckBoxChecked property. Here is an example of the code above running:
Putting It All Together
Hopefully this overview of Task Dialogs is not too daunting. Task Dialogs contain tons of functionality, and will be useful for you in many situations. The goal is for you to quickly start using Task Dialogs inside of your applications.
Where do you go from here? Go download the Windows API Code Pack. It provides numerous examples, including how to perform all the functions above. Have fun, and start enhancing your applications today.