Click here to Skip to main content
Click here to Skip to main content

A Versatile MessageBox

, 19 Oct 2009
Rate this:
Please Sign up or sign in to vote.
An easy and versatile MessageBox that allows you to use any number of buttons.

Introduction

Today, I decided that I needed a new messagebox to communicate with the user in a war-game I'm writing, and that's how I discovered that there were no ready-made buttons for a message box with the text "Charge" or "Cancel Attack" on them. Floundering around a bit to figure out how to get this done, I put a form together, and discovered that I could lock the system until it was either disposed or closed, by setting this form's owner to the calling form. But, closing this message box discarded the value of the reference variable 'reply' which I had passed to it, making it useless.

This, I decided, was a problem. And, after resolving to fix the issue, I came on-line to this site and found a few options that had their own complications, and I got some help from MSDN's C# General Forum which gave me the answer I needed for my war-game (click here), but a more generalized idea was nascent.

In this article, I will explain how to use classMessagebox, which allows users to easily invoke as many buttons as they want, call them whatever is their fancy, and give each button and/or main text its own font.

The Five-Step Programme

classMessageBox

The image above results from the test form's button event handler, shown here:

private void btnTestClassMessageBox_Click(object sender, EventArgs e)
{
    /// how to use
    /// 1) instantiate a new messagebox
    ///         input parameters : title, 
    ///                            text, 
    ///                            string of buttons separated by commas
    /// 2) set its owner so that the call to ShowDialog() 
    ///         locks the system onto this message box 
    ///         until it is closed or disposed
    /// 3) call ShowDialog();
    /// 4) use the Reply property to record which button was pressed
    /// 5) dispose of the messagebox

    classMessageBox msgBox
        = new classMessageBox("Message Box",
                              "This is a test",
                              "Button 1,Button 2,Vote Quimbey");
    msgBox.Owner = this;
    msgBox.ShowDialog();
    string reply = msgBox.Reply;
    msgBox.Dispose();
    Text = reply;
}

Points of Interest

Since the label and the array of buttons are both public in the class, you can change their fonts before calling ShowDialog(). These objects have event handlers to resize the form when their fonts change so that adding these two lines, for example:

msgBox.btns[2].Font = new Font("ms sans-serif", 18);
msgBox.lbl.Font = new Font("Lucida Console", 18, FontStyle.Italic);

gives you this:

classMessageBox

Your messagebox's reply is the same as the text written on the button which the user pressed. As long as you don't have two buttons with the same text, you'll know what the user wants.

Simple, flexible, and easy to use!

How it Works

There isn't very much in here to explain. It's all pretty straightforward. Really the only part that might be difficult is the resize() function, but first, let me start from the beginning and give you a brief tour.

The class inherits Form. It has a label and an empty array of buttons, and it receives three parameters, all of which are strings. The reply is a global variable which is treated like a property with its own 'get' routine.

When you instantiate a messagebox, the first two parameters are simply written where they belong, the first being the heading that goes to the Form's text proper, and the second parameter is set as the text of our label. You with me so far? Nothing to it.

The third parameter is where the fun starts. This string is split into an array of strings using a comma as a divisor. This array of strings is then run through, one at a time, and the strings are sent as parameters to a function which generates all the buttons, setting these strings as text for each button. Once all the buttons are created, complete with their FontChange and Click event-handlers, and included into the global array of buttons, then the resizing begins.

At this point, the resize function is called straight away, and this function then places the buttons left to right, from the left edge of the screen, with their AutoSize set to true and AutoSizeMode to ShrinkAndGrow. Once this is done, we know how wide our form has to be, so we set this value to fit all the buttons onto the form. Then, setting the Label's AutoSize value to true, we get a measure of the Label's width. The Resize function then calculates how many lines of text this Label will require if its width is greater than the width of the form. Now, we set the Label's AutoSize to false, and adjust its height to fit the number of lines we assume it will need (this does not account for any return carriage characters in the Label's text) by multiplying the number of lines times the Label's font height. Next, all the buttons have to be shifted down below the Label, and finally the form's height is set to fit the buttons.

And, we're done resizing this form.

When the font of one of the buttons (or the label) is changed, then that object's size may change as well, throwing our resized form's edge all a quiver. But, if we call resizeForm straight from the FontChange event-handler, then that object's size won't have adjusted already, so we have to wait, and calling that object's Refresh() doesn't solve your problem either; so to get this to work, you have to get the object to adjust its size to fit its new font, and sometimes all we need is time... so out comes the timer. The event handlers call initResize, which creates a timer and sets the timer's interval to the grand ole' value of 5 milliseconds and trips it to go. Five milliseconds to a computer, of course, is equivalent to something close to eternity, and so this gives your object plenty of time to adjust its size to fit its new font, and the time this timer trips and its Tick event is handled, the form is ready to be resized.

Vote Quimbey!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Christ Kennedy
CEO unemployable
Canada Canada
Christ Kennedy, published his fourth novel "Cleats of the Counter Revolution" in the summer of 2010. He grew up in the suburbs of Montreal and is a bilingual Quebecois with a bachelor’s degree in computer engineering from McGill University and is currently walking across ontario plotting a new novel, far away from any computer.

Comments and Discussions

 
Questionit worked for me!!! VS 2010 Pinmemberjleslie4821-Jun-11 2:09 
Generalparams are my new allies PinmemberChrist Kennedy20-Oct-09 13:30 
Generalarray of strings PinmemberChrist Kennedy20-Oct-09 12:43 
GeneralString of buttons parameter PinmemberToth Nandor20-Oct-09 1:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 20 Oct 2009
Article Copyright 2009 by Christ Kennedy
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid