问题描述
我对 C#.NET 下的表单形式有疑问.假设我有主表单#0(见下图).此表单代表主应用程序表单,用户可以在其中执行各种操作.但是,有时需要打开额外的非模态表单来执行额外的主要应用程序功能支持任务.假设这是图像中的表格#1.在这个 #1 表单上,可能会打开几个额外的模态表单(图像中的 #2 表单),最后,有一个进度对话框显示较长的操作进度和状态,这可能需要几个几分钟到几个小时.问题是主窗体#0 在您关闭所有模式窗体(图像中的#2)之前没有响应.我需要主窗体#0 在这种情况下可以运行.但是,如果您在表单#2 中打开一个非模态表单,您可以使用模态#2 表单和新创建的非模态表单进行操作.我需要主窗体#0 和窗体#1 及其所有子窗体之间的相同行为.是否可以?还是我做错了什么?也许有某种解决方法,我真的不想将所有 ShowDialog 调用更改为 Show...
I have a problem with modality of the forms under C#.NET. Let's say I have main form #0 (see the image below). This form represents main application form, where user can perform various operations. However, from time to time, there is a need to open additional non-modal form to perform additional main application functionality supporting tasks. Let's say this is form #1 in the image. On this #1 form there might be opened few additional modal forms on top of each other (#2 form in the image), and at the end, there is a progress dialog showing a long operation progress and status, which might take from few minutes up to few hours. The problem is that the main form #0 is not responsive until you close all modal forms (#2 in the image). I need that the main form #0 would be operational in this situation. However, if you open a non-modal form in form #2, you can operate with both modal #2 form and newly created non modal form. I need the same behavior between the main form #0 and form #1 with all its child forms. Is it possible? Or am I doing something wrong? Maybe there is some kind of workaround, I really would not like to change all ShowDialog calls to Show...
图片 http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png
推荐答案
模态表单完全符合模态"的含义,它们禁用应用程序中的所有其他窗口.这很重要,您的程序处于某种危险的状态.您有一大段代码正在等待对话框关闭.如果没有禁用其他窗口,可能会发生非常糟糕的事情.就像用户可以再次启动模式对话框一样,现在您的代码嵌套了两次.或者她可以关闭对话框的所有者窗口,现在它突然消失了.
Modal forms do exactly what "modal" means, they disable all other windows in the app. That's rather important, your program is in a somewhat perilous state. You've got a chunk of code that is waiting for the dialog to close. Really Bad Things could happen if those other windows were not disabled. Like the user could start the modal dialog again, now your code is nested twice. Or she could close the owner window of the dialog, now it suddenly disappears.
如果您在循环中调用 Application.DoEvents(),这些正是您会遇到的问题.这是在不禁用其他窗口的情况下让表单表现模态的一种方法.例如:
These are the exact kind of problems you'd run into if you call Application.DoEvents() inside a loop. Which is one way to get a form to behave modal 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();
}
这是危险的.
当然最好按照它们的设计方式使用模态表单以避免麻烦.如果您不想要模态表单,那么就不要将其设为模态,请使用 Show() 方法.订阅它的 FormClosing 事件以知道它即将关闭:
It is certainly best to use modal forms the way they were designed to stay out of trouble. If you don't want a modal form then simply don't make it modal, use the Show() method. Subscribe to its FormClosing event to know that 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>
//...
}
这篇关于WinForms 编程 - 模态和非模态表单问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!