Build a custom dialog in Windows Forms that is highly polished and professional in appearance. It must also comply with Microsoft's UI guidelines. MessageBox in .NET by default is ugly and doesn't adhere to the guidelines, and isn't adequate for a quality dialog. We must build a better dialog.
Here we have sample code for the customized dialog box. You can use the new dialog in your programs just as easily as you can use MessageBox.Show. The custom dialog has the following properties, many of which are not in the default MessageBox in Windows Forms .NET.
The dialog box method uses a simple static method to display the dialogs. It has a private constructor, so all you have to do is call its public method called ShowDialog. The following code sample is part of the code of the custom dialog. This part of the code implements ShowDialog, and then shows an example of calling ShowDialog.
/// <summary>
/// This method is part of the dialog, and provides a static calling method.
/// </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, but....",
"Reset", "Cancel", Properties.Resources.DialogWarningXP);
if (result == DialogResult.OK)
{
Console.WriteLine("User accepted the dialog");
}
}
The following code sample implements the basic logic, but lacks many of the details in my implementation. If you are reading this page, you may not need those details. If you are writing your own dialog, you can see some of the logic and method calls used and the general technique.
/// <summary>
/// Use this with the above static method. This is how the dialog is created.
/// I provide this code to show some implementation details. If you want the
/// full, working code, download the archive.
/// </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;
// Use IsNullOrEmpty to test strings.
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;
}
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 that the logic uses to construct and measure the final window. The complete logic is about 180 lines of C# code.
Adapt this to your specific requirements. Naturally, 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. Rigorously test your code to make sure it doesn't embarrass you down the line. For a better code view and downloads, visit my source code page.