Modal Dialogs

In Windows programming, a modal dialog is a window that demands attention. Nothing else can occur until we exit from that window. A simple example of this is a MessageBox control. It pops up and is in the foreground, which is to say that everything else is in the background. Until we click on the MessageBox to get rid of it, we can do nothing else.

It is possible to have much more elaborate modal dialogs, and there are various similar kinds of tricks.

Some common kinds of dialogs are dialogs to choose a color, choose a font or locate a file. There are more.


How can we imitate a modal dialog?

Suppose we have a form on which we have a button marked "Reveal" and some other control, (let's say it is a label). When we click on "Reveal", the handler changes the label's "Visible" property to "true", as in

     HideableLabel.Visible = true;

and the label (which had been invisible) is revealed. It appears to pop up, but in fact it was present all along, although hidden.

This is not a modal dialog. The appearance of the label does not by itself disable any of the other controls in the form.

It is worth noticing that the label will always appear in the same location, where we installed it by drag-and-drop.

What would happen if the user happened to click at a spot which is part of the hidden label? This event would be processed even though it might come as a surprise to the user.

As controls have a property called "Enabled" as well as "Visible", we could disable the hidden label when it is invisible:

     HideableLabel.Visible = true;
     HideableLabel.Enabled = true;

and when we want to make it invisible, we could also disable it:

     HideableLabel.Visible = false;
     HideableLabel.Enabled = false;

Likewise we could arrange for the event handler to disable all other controls in the form when the label becomes visible:

     private void DisableAll()
       {
       foreach (Control D in this.Controls)
        {
         D.Enabled = false;
        }
       }

and with a similar method they could all be enabled later.

This is beginning to sound more like a modal dialog.

Suppose we don't like the fixed location. It is quite possible to change the location. A control has a Location property providing the X and Y coordinates of its upper left corner. When we make the label visible, we can change the X and Y values. We could, for instance, generate them at random (although we want to be sure the control will fit inside the form).

Suppose we decide we don't want the label to be part of the form at all until it is needed, and we want it to go away again afterward. We could do the following:

If you put all of these ideas together, you can duplicate most of the functionality of a modal dialog.


How can we have a real modal dialog?

To have a true modal dialog, we need another form. Invent a second form class:

     public class Form2 : Form

and we will have to create everything in this form by writing code, not using drag-and-drop. In the constructor we can specify various details of the form (size, name) and of whatever controls we want inside this form. Be sure to add each control to the form. We will need to provide an event handler for loading the form:

     this.Load += new System.EventHandler(this.Form2_Load);

and we will need to write code for the handler, even if it has an empty body.

We will also need to provide event handlers (and code for them) for the events of the controls in the form.

In the original form, we presumably have an event (clicking a button) to call up the modal form. In the handler for that event, we need:

     Form2 NewForm = new Form2();
     NewForm.ShowDialog();

What actually makes this modal is "ShowDialog". All of the original form is now frozen until we are done with the modal form.

An option is to use:

     NewForm.Show();

instead, in which case we do not have a modal dialog and both forms are still active. The Show() method basically just sets Visible to true. There is also a Hide() method.

Notice that NewForm is a local variable inside a method. When the method exits, NewForm presuambly goes away.