C# Customized Dialog Box

MessageBox doesn't adhere to some UI guidelines. Here we have sample code for a customized dialog box. And you can use the new dialog in your programs just as easily as you can use MessageBox.Show.

MessageBox.ShowCustom dialog box

ShowDialog

Here we can use a special static method. It has a private constructor. We call its public method called ShowDialog. The following code sample is part of the code of the custom dialog. Here we implement ShowDialog, and then call it.

Implementation of ShowDialog: C#

/// <summary>
/// This method is part of the dialog.
/// </summary>
static public DialogResult ShowDialog(string title,
    string largeHeading,
    string smallExplanation,
    string leftButton,
    string rightButton,
    Image iconSet)
{
    // Call the private constructor so the users only need to call this
    // function, which is similar to MessageBox.Show.
    // Returns a standard DialogResult.
    using (BetterDialog dialog = new BetterDialog(title, largeHeading,
	smallExplanation, leftButton, rightButton, iconSet))
    {
	DialogResult result = dialog.ShowDialog();
	return result;
    }
}

/// <summary>
/// This is the calling convention of the above method.
/// Use this to show a custom dialog in your source code.
/// </summary>
private void ExampleCall()
{
    DialogResult result = BetterDialog.ShowDialog("Reset Journal Settings",
	"Settings will be erased permanently",
	"This will not affect any of the text content in the database.",
	"Reset", "Cancel", Properties.Resources.DialogWarningXP);

    if (result == DialogResult.OK)
    {
	Console.WriteLine("User accepted the dialog");
    }
}
Note

The above code uses several arguments. The first arguments are for the title, heading, text and buttons.
If you want a button not to appear,
pass in null instead of a string,
and it won't be shown.

Button usage. It has a default button. In my implementation, the first button is always the default and it is also the confirm button. This matches Microsoft's guidelines. You can find more information on Button controls here.

Button in Windows Forms

Custom image usage. It shows a custom Image. The last argument is an Image resource called DialogWarningXP. You can use an Image from your program's resources, and BetterDialog will use that as its icon.

DialogResult example

Finally:It returns a standard DialogResult, which you can test as normally by using DialogResult.OK or other enums on DialogResult.

DialogResult: Windows Forms

Logic

The following code sample implements the basic logic, but lacks many of the details in my implementation. If you are writing your own dialog, you can see some of the logic and method calls used and the general technique.

Implementation of BetterDialog constructor: C#

/// <summary>
/// Use this with the above static method.
/// </summary>
private BetterDialog(string title,
    string largeHeading,
    string smallExplanation,
    string leftButton,
    string rightButton,
    Image iconSet)
{
    // Set up some properties.
    this.Font = SystemFonts.MessageBoxFont;
    this.ForeColor = SystemColors.WindowText;
    InitializeComponent();
    this.Width = 350;
    this.Height = 150;

    // Do some measurements with Graphics.
    using (Graphics graphics = this.CreateGraphics())
    {
	SizeF smallSize;
	SizeF bigSize;

	if (string.IsNullOrEmpty(smallExplanation) == false)
	{
	    // Note: at this point, we could detect that the OS is Vista
	    // and do some customizations. That logic is in the download.
	    // The code here does some measurements.
	    label1.Font = new Font(SystemFonts.MessageBoxFont.FontFamily.Name, 8.0f,
		FontStyle.Bold, GraphicsUnit.Point);
	    smallSize = graphics.MeasureString(smallExplanation, this.Font,
		this.label2.Width);
	    bigSize = graphics.MeasureString(largeHeading, label1.Font,
		this.label1.Width);
	    this.Height = (int)smallSize.Height + 166;
	    double bigger = (smallSize.Width > bigSize.Width) ?
		smallSize.Width : bigSize.Width;
	    this.Width = (int)bigger + 100;
	}
	else
	{
	    // We have a null "smallExplanation", so we have a single message
	    // dialog. Do some different changes. Code omitted for brevity (you
	    // can find the logic in the download if you want to see it).
	}
    }

    // Establish a minimum width.
    if (this.Width < 260)
    {
	this.Width = 260;
    }

    // Set the title, and some Text properties.
    this.Text = title;
    label1.Text = largeHeading;
    label2.Text = string.IsNullOrEmpty(smallExplanation) ?
	string.Empty : smallExplanation;

    // Set the left button, which is optional.
    if (string.IsNullOrEmpty(leftButton) == false)
    {
	this.buttonLeft.Text = leftButton;
    }
    else
    {
	this.AcceptButton = buttonRight;
	this.buttonLeft.Visible = false;
    }
    this.buttonRight.Text = rightButton;

    // Set the PictureBox and the icon.
    pictureBox1.Image = iconSet;
}
Squares

The above dialog code uses the CreateGraphics method. It uses this.CreateGraphics to get a Graphics object on the form. It uses a bit of logic with MeasureString and attempts to lay out the dialog.

Layout issues. It has const values. I had to painstakingly find several const values that would lay out and position the dialog's elements properly. It also has a table layout, which simplifies the design.

Note:The layout is done with two TableLayout panels, with a white background so that it can better match Windows' themes.

Const ExampleTableLayoutPanel in Windows Forms

Hiding and showing cells. It can hide or show parts. It can hide or show various parts of the itself. It will hide buttons you specify as null, and it will collapse and hide the text if you don't supply it.

Properties

Property

This dialog has some special attributes. The custom dialog has the following properties, many of which are not in the default MessageBox in Windows Forms. It is simpler to use: you can just pass in different arguments.

It uses the proper fonts. It uses Segoe UI font on Vista, and Tahoma on XP. Header text and layout is precisely equal to the Vista standard, which says you should have larger header text on the dialog.

It allows custom button text. Supports action verbs as its confirm button, and also 1 or 2 buttons. It allows custom icons. Can use custom icons—pass in an Image resource and it will displayed as the alert message.

Designer

Here is a picture of the form in the Visual Studio 2008 Designer.
You can see the basic layout,
with two TableLayoutPanel controls
and the PictureBox. This is the basic skeleton of the custom dialog.

Custom dialog: designer view

Download

You can download the source files to this better dialog code by visiting the appropriate Google Code repository. There is a zip file you can download that contains the source text. This dialog may have dependencies on external images.

Google Code site

Summary

Framework: NET

Here we saw an example of a custom dialog in the C# language. Unfortunately, there are some weaknesses here. It can look odd in real edge-cases, such as a dialog with the text of War and Peace in it.

Tip:Rigorously test your code to make sure it doesn't embarrass you down the line.


C#: Windows