Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dialog Message in C# for .NET Framework 4.5

0.00/5 (No votes)
25 Apr 2020 1  
A reference for writing your own dialog message box in Windows
This project outlines the logic necessary to write your own dialog message box in Windows. This is not meant to be a step-by-step tutorial on how to use Visual Studio or the C# programming language but an overview of the logic necessary to develop your own message box. The code snippets in the code section have lots of comments to help understand what each piece is doing.

Image 1

Table of Contents

  1. Introduction
  2. Before We Move Ahead
  3. Implementation
  4. Form Design
  5. Code
    1. Structure
    2. Events and Methods
  6. Conclusion
  7. History

Introduction

Around the time I started programming, I discovered the MessageBox class in the standard .NET Framework library. This was exciting because it allowed me to experiment with different ways of providing myself information about what was happening in my applications. This was well and good until I saw a particular message box while I was using Windows for personal use. I would eventually come to learn that this message box was actually called a TaskDialog, which was introduced in Windows Vista. It had blue text on the top and some smaller black text at the bottom. Understanding how to use a TaskDialog at the time was beyond my skill set so I decided to try and create a similar looking one using the skills I had at the time.

In this project, we will write our own dialog message box using Visual Studio and the Designer with C#. It will support two styles of text, three button configurations, and six icon configurations. The icons utilized are from the SystemIcons class.

Before We Move Ahead

This is not meant to be a step-by-step tutorial on how to use Visual Studio or the C# programming language but an overview of the logic necessary to develop your own message box. The code snippets in the code section have lots of comments to help understand what each piece is doing. Below is a list of topics that are assumed you are familiar with:

Implementation

Here is an implementation of the message. This code will show the message as it appears in the image at the beginning of the article.

using DialogMessage;

if (DMessage.ShowMessage(

    // Window Title
    "Window Title",

    // Main Instruction
    "Want to learn how to write your own message box?",

    // Dialog buttons
    DMessage.MsgButtons.YesNo,

    // Dialog Icons
    DMessage.MsgIcons.Question,

    // Content
    "In this project we will learn the logic necessary " +
    "to write your own dialog message box in Windows")

    // Checks DialogResult of the button clicked by user
    == DialogResult.Yes)

    // Show the Windows standard MessageBox to test result
    MessageBox.Show("You clicked Yes!");

else

    MessageBox.Show("You clicked No!");

Form Design

The image below is the Form Designer view of MainForm.Designer.cs with controls and some notable properties. Important properties to notice are Anchor,  MaximumSize, and FormBorderStyle.

Anchor ensures that the controls on the Form move appropriately as it re-sizes.

MaximumSize of the Labels ensures that the text does not spill off the Form and will wrap to a new line.

FormBorderStyle set to FixedDialog ensures that the user cannot re-size the Form allowing it to re-size based on the amount of text provided.

Image 2

Code

Structure

The message box is split up into two main files; MainForm.cs and DialogMessage.cs.

MainForm.cs contains the following Form.Load event:

// Form.Load event
private void DialogMessage_Load(object sender, EventArgs e) 
{
      // Set the starting locations and sizes of the labels
      // Adjust the locations and sizes of the labels to properly show the information
}

DialogMessage.cs contains the following three code blocks below; a public static method and two enum's:

/// <summary>
/// A public static method with a return value of System.Windows.Forms.DialogResult
/// </summary>
/// <param name="_windowTitle"></param>
/// <param name="_mainInstruction"></param>
/// <param name="_msgButtons"></param>
/// <param name="_msgIcons"></param> // Optional parameter with default value of None
/// <param name="_content"></param> // Optional parameter with empty default value
/// <returns></returns>
public static DialogResult ShowMessage(string _windowTitle,
                                       string _mainInstruction, 
                                       MsgButtons _msgButtons,
                                       MsgIcons _msgIcons = MsgIcons.None,
                                       string _content = "") 
{
      // Set button and icon configurations and show the information to the user
}
// Message button enum for switch statement in ShowMessage
// This will set the properties of the form buttons and their DialogResult
public enum MsgButtons
{
      OK = 0,
      OKCancel = 1,
      YesNo = 2
}
// Message icon enum for switch statement in ShowMessage
// This will set the Image for the PictureBox
public enum MsgIcons
{
    None = 0,
    Question = 1,
    Info = 2,
    Warning = 3,
    Error = 4,
    Shield = 5
}

Events and Methods

Let's go into each code block to see what it does.

Form.Load event in MainForm.cs:

private void DialogMessage_Load(object sender, EventArgs e)
{
    // Once the ShowMessage function is called and the form appears
    // the code below makes the appropriate adjustments so the text appears properly

    // If no icon will be shown then shift the MainInstruction and Content 
    // left to an appropriate location

    // Adjust the MaximumSize to compensate for the shift left.
    if (msgIcon.Visible == false)
    {
        mainInstruction.Location = new Point(12, mainInstruction.Location.Y);
        mainInstruction.MaximumSize = new Size(353, 0);

        content.Location = new Point(12, content.Location.Y);
        content.MaximumSize = new Size(353, 0);
    }

    // Gets the Y location of the bottom of MainInstruction
    int mainInstructionBottom = mainInstruction.Location.Y + mainInstruction.Height;

    // Gets the Y location of the bottom of Content
    int contentBottom = content.Location.Y + content.Height;

    // Offsets the top of Content from the bottom of MainInstruction
    int contentTop = mainInstructionBottom + 18; // 18 just looked nice to me

    // Sets new location of the top of Content
    content.Location = new Point(content.Location.X, contentTop);

    if (content.Text == string.Empty)

        // If only MainInstruction is provided then make the form a little shorter
        Height += (mainInstruction.Location.Y + mainInstruction.Height) - 50;
    else
        Height += (content.Location.Y + content.Height) - 60;
}

ShowMessage method in DialogMessage.cs:

public static DialogResult ShowMessage(string _windowTitle,
                                        string _mainInstruction,
                                        MsgButtons _msgButtons,
                                        MsgIcons _msgIcons = MsgIcons.None,
                                        string _content = "")
{
    // Creates a new instance of MainForm so we can set the properties of the controls
    MainForm main = new MainForm();

    // Sets the initial height of the form
    main.Height = 157;

    // Sets Window Title
    main.Text = _windowTitle;

    // Sets MainInstruction
    main.mainInstruction.Text = _mainInstruction;

    // Sets Content
    main.content.Text = _content;

    // Sets the properties of the buttons based on which enum was provided
    switch (_msgButtons)
    {
        // Button1 is the left button
        // Button2 is the right button

        case MsgButtons.OK:
            
            main.Button1.Visible = false;
            main.Button2.DialogResult = DialogResult.OK;
            main.Button2.Text = "OK";
            main.AcceptButton = main.Button2; 
            main.Button2.TabIndex = 0;
            main.ActiveControl = main.Button2;

            break;

        case MsgButtons.OKCancel:

            main.Button1.DialogResult = DialogResult.OK;
            main.Button2.DialogResult = DialogResult.Cancel;
            main.Button1.Text = "OK";
            main.Button2.Text = "Cancel";
            main.AcceptButton = main.Button2; 
            main.Button1.TabIndex = 1;
            main.Button2.TabIndex = 0;
            main.ActiveControl = main.Button2;

            break;

        case MsgButtons.YesNo:

            main.Button1.DialogResult = DialogResult.Yes;
            main.Button2.DialogResult = DialogResult.No;
            main.Button1.Text = "Yes";
            main.Button2.Text = "No";
            main.AcceptButton = main.Button2; 
            main.Button1.TabIndex = 1;
            main.Button2.TabIndex = 0;
            main.ActiveControl = main.Button2;

            break;

        default:
            break;
    }

    // Sets the Image for the PictureBox based on which enum was provided
    if (_msgIcons != MsgIcons.None)
    {
        main.msgIcon.Visible = true;

        switch (_msgIcons)
        {
            case MsgIcons.Question:

                main.msgIcon.Image = SystemIcons.Question.ToBitmap();
                break;

            case MsgIcons.Info:

                main.msgIcon.Image = SystemIcons.Information.ToBitmap();
                break;

            case MsgIcons.Warning:

                main.msgIcon.Image = SystemIcons.Warning.ToBitmap();
                break;

            case MsgIcons.Error:

                main.msgIcon.Image = SystemIcons.Error.ToBitmap();
                break;

            case MsgIcons.Shield:

                main.msgIcon.Image = SystemIcons.Shield.ToBitmap();
                break;

            default:
                break;
        }
    }
    else
    {
        main.msgIcon.Visible = false;
    }

    // Shows the message and gets the result selected by the user
    return main.ShowDialog();
}

Conclusion

I hope you have found this article useful. I realize that there are already some in-depth articles on CodeProject about message box alternatives and wrappers for the Windows TaskDialog (which inspired this project), however, I wanted this to be a reference for learning how to write your own.

History

  • 25th April, 2020
    • Added icon functionality. Icons utilized are from the SystemIcons class.
  • 18th April, 2020
    • Re-designed the code to use a static class and method. This eliminated the need to create a new instance of DialogMessage.
  • 13th April, 2020
    • Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here