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

Custom Featured MessageBox

0.00/5 (No votes)
11 Feb 2008 1  
A MessageBox that works as we want.

Introduction

We often require the MessageBox while developing programs, and it's a very helpful tool to communicate with users. Sometimes, we want the MessageBox to look like a part of our application or match with the application theme, but it may not be possible always. For instance, we use LightSkyBlue as the background color for all our forms in an application but when we show a MessageBox, its style is always the same. A MessageBox would look odd and weird in this combination. In other words, we can say that we don’t have full control on MessageBox control. So, why don’t we make our own MessageBox that will work as we want, where we can have full control on it.

I wasted a lot of my precious time in searching for a solution for this, but I never found it anywhere. So, I planned to make it myself. After a lot of R&D, at last, I did it. And now, I think that I should share my solution to those who have the same problem. At the end of this article, the reader will have a customized MessageBox on which, he/she will have full control.

Designing

Create a new project, name it “Custom Featured MessageBox”, open its properties, and set “Output Type” to “Class Library” (because Class Library output will be a DLL that can be easily added to any project). Add a new project in the same solution, name it “Test”, right click on it, and hit “Set as StartUp Project”. Now, back to the “Custom Featured MessageBox” project.

We will require:

  • A Windows Form
  • A PictureBox, to show an icon
  • A TextBox, to show text (we cannot use Label here because we will require to count the lines)
  • Three Buttons, for dialog results
  • Three Panels, to keep all the controls in the correct locations and size

Set the control properties as:

Form:
Name: XMessageBox
ControlBox: False
FormBorderStyle: FixedSingle
Max.Box: False
Min.Box: False
Padding: 10, 10, 10, 0
ShowIcon: False
ShowInTaskbar: False
Size: 262, 104
StartPosition: CenterScreen

TextBox:
BackColor: Control
BorderStyle: None
Dock: Fill
MaxLength: 0 (i.e. Max Length)
Multiline: True
ReadOnly: True
TabStop: False
TextAlign: Center

Panels:

Panel 1:
Name: leftPanel
Dock: Left
Visible: False
    Controls:
           PictureBox
Panel 2:
Name: bottomPanel
Dock: Bottom
    Controls:
           Panel 3
Panel 3 :
Name: bottomInnerPanel
Location: 0, 0
Size: 236, 30
    Controls:
           Button 1
           Button 2
           Button 3

PictureBox:
BackgroundImageLayout: Stretch
Location: 0, 0
Size: 32, 32

Button 1:
Location: 0, 3
Visible: False

Button 2:
Location: 81, 3
Visible: False

Button 3:
Location: 162, 3
Visible: False

Well done!!! Now, it will look like:

1.jpg

Using the code

First, create two const member variables of type int.

const int minWidth = 262;
const int maxWidth = 600;

Then, we have to create two enums, XMessageBoxButtons and XMessageBoxIcon, with public modifiers:

public enum XMessageBoxButtons
{ OK, AbortRetryIgnore, YesNoCancel, YesNo, RetryCancel, }
public enum XMessageBoxIcon
{ Error, Question, Warning, Information, }

After this, create two methods SetButtons and SetIcon to set the buttons and icons, respectively:

void SetButtons(XMessageBoxButtons buttons)
{
    if (buttons == XMessageBoxButtons.OK)
    {
        button2.Visible = true;
        button2.Text = "OK";
        button2.DialogResult = DialogResult.OK;
        ControlBox = true;
    }
    else if (buttons == XMessageBoxButtons.AbortRetryIgnore)
    {
        button1.Visible = true;
        button1.Text = "Abort";
        button1.DialogResult = DialogResult.Abort;
        button2.Visible = true;
        button2.Text = "Retry";
        button2.DialogResult = DialogResult.Retry;
        button3.Visible = true;
        button3.Text = "Ignore";
        button3.DialogResult = DialogResult.Ignore;
        if (this.Width < minWidth)
            this.Width = minWidth;
    }
    else if (buttons == XMessageBoxButtons.RetryCancel)
    {
        button1.Visible = true;
        button1.Text = "Retry";
        button1.DialogResult = DialogResult.Retry;
        button1.Location = new Point(41, 3);
        button2.Visible = true;
        button2.Text = "Cancel";
        button2.DialogResult = DialogResult.Cancel;
        button2.Location = new Point(122, 3);
        if (this.Width < minWidth)
            this.Width = minWidth;
    }
    else if (buttons == XMessageBoxButtons.YesNo)
    {
        button1.Visible = true;
        button1.Text = "Yes";
        button1.DialogResult = DialogResult.Yes;
        button1.Location = new Point(41, 3);
        button2.Visible = true;
        button2.Text = "No";
        button2.DialogResult = DialogResult.No;
        button2.Location = new Point(122, 3);
        if (this.Width < minWidth)
            this.Width = minWidth;
    }
    else if (buttons == XMessageBoxButtons.YesNoCancel)
    {
        button1.Visible = true;
        button1.DialogResult = DialogResult.Yes;
        button1.Text = "Yes";
        button2.Visible = true;
        button2.DialogResult = DialogResult.No;
        button2.Text = "No";
        button3.Visible = true;
        button3.DialogResult = DialogResult.Cancel;
        button3.Text = "Cancel";
        if (this.Width < minWidth)
            this.Width = minWidth;
    }
}

void SetIcon(XMessageBoxIcon icon)
{
    if (this.Height < 104)
        this.Height = 104;
    if (this.Width <= 600)
        this.Width += 55;
    leftPanel.Visible = true;
    if (icon == XMessageBoxIcon.Information)
        pictureBox1.BackgroundImage = 
          Custom_Featured_MessageBox.Properties.Resources.Information; 
    // Images have been added to Resources
    else if (icon == XMessageBoxIcon.Warning)
        pictureBox1.BackgroundImage = 
          Custom_Featured_MessageBox.Properties.Resources.Warning;
    else if (icon == XMessageBoxIcon.Error)
        pictureBox1.BackgroundImage = 
          Custom_Featured_MessageBox.Properties.Resources.Error;
    else if (icon == XMessageBoxIcon.Question)
        pictureBox1.BackgroundImage = 
          Custom_Featured_MessageBox.Properties.Resources.QuestionMark;
}

Now, we should create a method that will set the entire message box. Name it XmessageBox, and with seven arguments:

void XmessageBox(string text, string title, Size size, Font font, 
     Color backColor, Color foreColor, bool customSize)
{}

Next, write code in it so that it can set the message box when called:

int width;
int height;

this.Text = title;
TextBox1.Text = text;
this.Font = font;
this.BackColor = backColor;
this.ForeColor = foreColor;

Graphics g = this.CreateGraphics(); // Initiating
SizeF textSize = g.MeasureString(text, font);
g.Dispose();
//|==================================================//
//|------------                                      //
//|CALCULATIONS                                      //
//|------------                                      //            
//|15, adjustment                                    //
//|==================================================//            
if (textSize.Width <= maxWidth)
    width = (int)textSize.Width + 15;
else
    width = maxWidth;

//|==================================================//
//|------------                                      //
//|CALCULATIONS                                      //
//|------------                                      //
//|30 + 10 = 40, panal height + form's top padding   //            
//|40, adjustment                                    //
//|==================================================//
height = (TextBox1.Lines.Length * TextBox1.Font.Height) + 40 + 40;

if (customSize == true)  // set size only when customSize is true
    this.Size = size;
else
    this.Size = new Size(width, height);

When finished, select the form (XMessageBox), double click on the Resize event, and write these two lines, to keep all the dialog buttons at the middle of the form.

int x = (bottomPanel.Width - bottomInnerPanel.Width) / 2;
bottomInnerPanel.Location = new Point(x, bottomInnerPanel.Location.Y); // Y will same

Also, double click on the BackColorChanged as well as ForeColorChanged events, to set Textbox1 colors when the form colors change.

private void XMessageBox_ForeColorChanged(object sender, EventArgs e)
{
    TextBox1.ForeColor = this.ForeColor;
}
private void XMessageBox_BackColorChanged(object sender, EventArgs e)
{
    TextBox1.BackColor = this.BackColor;
}

Create a static method to show XMessageBox (because static methods can be called without making instance). Name it show, with an argument and a DialogResult return type.

public static  DialogResult show(string text)
{}

Write code in it:

XMessageBox f = new XMessageBox();
f.XmessageBox(text, "", f.Size, f.Font, f.BackColor, f.ForeColor, false);
f.SetButtons(XMessageBoxButtons.OK); // if button is not specified, then set OK
return f.ShowDialog();

In this code, we are making an instance of XMessageBox and calling some of its required methods. We are not calling SetIcon here, because this static method will only show a simple message box.

Next, add twelve more methods, to overload this method:

public static DialogResult show(string text, string title)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, f.Size, f.Font, f.BackColor, f.ForeColor, false);
    f.SetButtons(XMessageBoxButtons.OK); // if button is not specified
    return f.ShowDialog();
}
public static 
    DialogResult show(string text, string title, XMessageBoxButtons buttons)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, f.Size, f.Font, f.BackColor, f.ForeColor, false);
    f.SetButtons(buttons);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, 
       XMessageBoxButtons buttons, XMessageBoxIcon icon)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, f.Size, f.Font, f.BackColor, f.ForeColor, false);
    f.SetButtons(buttons);
    f.SetIcon(icon);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, 
              XMessageBoxButtons buttons, Size size)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, size, f.Font, f.BackColor, f.ForeColor, true);
    f.SetButtons(buttons);
    return f.ShowDialog();
}

public static DialogResult show(string text, string title, 
              XMessageBoxButtons buttons, XMessageBoxIcon icon, Size size)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, size, f.Font, f.BackColor, f.ForeColor, true);
    f.SetButtons(buttons);
    f.SetIcon(icon);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, 
              XMessageBoxButtons buttons, Size size, Font font)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, size, font, f.BackColor, f.ForeColor, true);
    f.SetButtons(buttons);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, XMessageBoxButtons buttons, 
              XMessageBoxIcon icon, Size size, Font font)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, size, font, f.BackColor, f.ForeColor, true);
    f.SetButtons(buttons);
    f.SetIcon(icon);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, 
              Color backColor, Color foreColor)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, f.Size, f.Font, backColor, foreColor, false);
    f.SetButtons(XMessageBoxButtons.OK);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, 
       Color backColor, Color foreColor, XMessageBoxButtons buttons)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, f.Size, f.Font, backColor, foreColor, false);
    f.SetButtons(buttons);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, Color backColor, 
              Color foreColor, XMessageBoxButtons buttons, XMessageBoxIcon icon)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, f.Size, f.Font, backColor, foreColor, false);
    f.SetButtons(buttons);
    f.SetIcon(icon);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, Color backColor, 
              Color foreColor, XMessageBoxButtons buttons, Size size, Font font)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, size, font, backColor, foreColor, true);
    f.SetButtons(buttons);
    return f.ShowDialog();
}
public static DialogResult show(string text, string title, Color backColor, Color foreColor, 
              XMessageBoxButtons buttons, XMessageBoxIcon icon, Size size, Font font)
{
    XMessageBox f = new XMessageBox();
    f.XmessageBox(text, title, size, font, backColor, foreColor, true);
    f.SetButtons(buttons);
    f.SetIcon(icon);
    return f.ShowDialog();
}

Back to the Test project, right click on “References”, select “Add Reference…”, then tab to “Projects”, press “OK” after selecting “Custom Featured MessageBox”. When done, add a namespace reference in Form1.

using Custom_Featured_MessageBox;

Add a Button, double click on it, and write code:

XMessageBox.show("Simple MessageBox with OK button, BackColor is LightSkyBlue " + 
                 "and ForeColor is Black.", "Example", 
                 Color.LightSkyBlue, Color.Black, XMessageBoxButtons.OK);
XMessageBox.show("Simple MessageBox with Abort, Retry and Ignore buttons, BackColor" + 
                 " is LightCyan and ForeColor is Black.", "Example", 
                 Color.LightCyan, Color.Black, XMessageBoxButtons.AbortRetryIgnore);
XMessageBox.show("Error MessageBox with OK button, BackColor is LightGreen " + 
                 "and ForeColor is Black.", "Example", Color.LightGreen, 
                 Color.Black, XMessageBoxButtons.OK, XMessageBoxIcon.Error);
XMessageBox.show("Information MessageBox with Yes and No buttons, BackColor " + 
                 "is LightPink and ForeColor is Black.", "Example", 
                 Color.LightPink, Color.Black, XMessageBoxButtons.YesNo, 
                 XMessageBoxIcon.Information);

Now, it's time to check our custom message box. Run the solution, click the button, and see the result:

2.jpg

Now, we got a problem that it’s just showing one line. The word “Black”, which is in the second line, is not appearing (since word-wrap is enabled, “Black” is in the second line). Obviously, the problem is in the height setting. Let's check the cause out. We need to search for where we are setting the height. And, we reach the XmessageBox method, where we have:

height = (TextBox1.Lines.Length * TextBox1.Font.Height) + 40 + 40;

…to set the height, put a breakpoint on that line so that we can know the current values.

Points of interest

Run again, when the compiler stops at the breakpoint, hover the mouse on Length of TextBox1.Lines (first value, which is going to set the height), and we see that this property is returning "1". However, TextBox1 contains two lines. That means, the Length property doesn’t work properly when word-wrap is on. Therefore, we need to count the lines explicitly. To do that, add a class. Now, replace all its text with this:

using System;
using System.Windows.Forms;
namespace Custom_Featured_MessageBox
{
    public class XTextBox : TextBox
    {
        public int LinesCount()
        {
            Message msg = Message.Create(this.Handle, 0xBA, 
                          IntPtr.Zero, IntPtr.Zero);
            base.DefWndProc(ref msg);
            return msg.Result.ToInt32();
        }     
    }
}

In the above code, TextBox is inherited, and added with a method named LinesCount that will return the exact line length whether word-wrap is enabled or not. In this method, we are sending a message to the default window procedure of the base class as a reference. And that's all.

Replace the default TextBox with a new one as well as replace TextBox1.Lines.Length with TextBox1.LinesCount(). Now, the replaced line will look like:

height = (TextBox1.LinesCount() * TextBox1.Font.Height) + 40 + 40;

Now, Run, oh yeah!!! It's working….!!!

We can also add our own image as an icon. To do that:

  1. Add the image in Resources.
  2. Add the name (any) in the XMessageBoxIcon enum.
  3. Expand the SetIcon method.

For example, if we want to add a ‘Delete’ image as an icon, then just add the ‘Delete’ image in Resources, and expand the XMessageBoxIcon enum:

public enum XMessageBoxIcon
{ Error, Question, Warning, Information, Delete, }

Expand “SetIcon” as well:

void SetIcon(XMessageBoxIcon icon)
{ 
.
.
.
.
    else if (icon == XMessageBoxIcon.Delete)
        pictureBox1.BackgroundImage = 
          Custom_Featured_MessageBox.Properties.Resources.Delete;
}

Now, call XmessageBox with that icon:

XMessageBox.show("Delete MessageBox with Yes, No and " + 
                 "Cancel buttons, BackColor is Control and ForeColor is Black.", 
                 "Example", XMessageBoxButtons.YesNoCancel, 
                 XMessageBoxIcon.Delete);

At the end, we have a message box that will do whatever we want. Please rate this article, only if you have read it from start to end.

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