WinForms Programming - The Problem of Modal and Non-Modal Forms

I have a problem with form modalities in C # .NET. Say I have a basic form number 0 (see image below). This form is the main application form, where the user can perform various operations. However, from time to time it becomes necessary to open an additional modeless form to perform additional support functions for the main applications. Let's say this is form number 1 in the image. In this form # 1, several additional modal forms can be opened one above the other (form # 2 in the image), and at the end there is a progress dialog showing the long course of the operation and the status, which can take from several minutes to several hours. The problem is that main form # 0 does not respond until you close all modal forms (# 2 in the image). I need the main form number 0 to be workable in this situation. However, if you open a non-modal form in form No. 2, you can work with both modal form No. 2 and the new non-modal form. I need the same behavior between main form # 0 and form # 1 with all its child forms. Is it possible? Or am I doing something wrong? Perhaps there is some workaround, I really would not want to change all the ShowDialog calls for Show ...

Image http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png

+6
c # forms modal-dialog
source share
5 answers

Modal forms do exactly what β€œmodal” means; they turn off all other windows in the application. This is very important, your program is in a somewhat dangerous state. You have a piece of code waiting for the dialog to close. Indeed, bad things can happen if these other windows have not been disabled. Just as the user can start the modal dialog again, now your code is nested twice. Or she can close the dialog box owner window, now it suddenly disappears.

These are the exact problems you encountered if you call Application.DoEvents () inside the loop. This is one way to make the form behave modally without disabling other windows. For example:

Form2 mDialog; private void button1_Click(object sender, EventArgs e) { mDialog = new Form2(); mDialog.FormClosed += (o, ea) => mDialog = null; mDialog.Show(this); while (mDialog != null) Application.DoEvents(); } 

This is dangerous.

Of course, it is better to use modal forms in the way they were designed so as not to disturb. If you do not need a modal form, just do not make it modal, use the Show () method. Subscribe to the FormClosing event to find out what it is about to close:

  private void button1_Click(object sender, EventArgs e) { var frm = new Form2(); frm.FormClosing += new FormClosingEventHandler(frm_FormClosing); frm.Show(); } void frm_FormClosing(object sender, FormClosingEventArgs e) { var frm = sender as Form2; // Do something with <frm> //... } 
+12
source share

The first thing that comes to mind would be something like this. You can disable form 1 when running form 2, and then form 1 to close the closed event of the second form to enable it again. You would not open modal 2 using the show dialog.

Now keep in mind that from the user's point of view this will be rather cumbersome, you can see how to make an MDI application to get all the windows inside one container.

+3
source share

Your main form will not respond until any modal dialogs that are in the same process space are closed. There is no work for this.

0
source share

It seems to me that you can use the MDI application to set the form property # 0 IsMdiContainer to true.

Then you can do something similar:

 public partial class Form0 { public Form0 { InitializeComponent(); this.IsMdiContainer = true; // This will allow the Form #0 to be responsive while other forms are opened. } private void button1_Click(object sender, EventArgs e) { Form1 newForm1 = new Form1(); newForm1.Parent = this; newForm1.Show(); } } 

Using ShowDialog () , as you stated in your question, make all forms Modal = true .

By definition, the modal form:

When a form is displayed modally, input (keyboard or mouse) cannot be performed except for objects in the modal form. A program must hide or close a modal form (usually in response to some user action) before entering another form. Forms displayed modally are typically used as dialog boxes in an application.

You can use this [( Modal )] property to determine if the form you received from the method or property is displayed in format.

Thus, the modal form should only be used when you need immediate help / user interaction. Using modal forms otherwise means that you may be working in the wrong direction.

If you do not want your main form to be an MDI container, then perhaps using multithreading is one of the solutions using a simple BackgroundWorker class is the key to what you want to achieve. So it looks like a designer smell ...

  • What do you want to do, besides having your main form react, etc.
  • What do you need to do?

Explaining what you need to do, we could lead you in the right direction, or at least in the best direction.

0
source share

Actually the answer is very simple. Try

 newForm.showDialog(); 

This will open a new form, and the parent is not available.

-one
source share

All Articles