WinForms编程 - Modal和Non-Modal形成问题 [英] WinForms programming - Modal and Non-Modal forms problem

查看:400
本文介绍了WinForms编程 - Modal和Non-Modal形成问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#.NET下的表单模式存在问题。假设我的主要形式为#0(请参阅下图)。该表格代表主要申请表格,用户可以在其中执行各种操作。但是,有时需要打开额外的非模态表单来执行支持任务的其他主要应用程序功能。假设这是图像中的#1形式。在这个#1表单上可能会打开几个额外的模式形式(图像中的#2表单),最后还有一个进度对话框,显示一个长时间的操作进度和状态,这可能需要很少的时间分钟到几个小时。问题在于,除非关闭所有模态窗体(图像中的#2),否则主窗体#0无法响应。我需要在这种情况下主要的#0格式可以运行。但是,如果您在表单#2中打开非模式表单,则可以使用模式2表单和新创建的非模式表单进行操作。我需要主窗体#0和窗体#1与其所有子窗体之间的相同行为。可能吗?或者我做错了什么?也许有某种解决方法,我真的不想将所有ShowDialog调用改为显示...



图片http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png

解决方案

模态形式完全符合模式的含义,它们会禁用应用中的所有其他窗口。这很重要,你的程序处于危险的状态。你有一大块代码正在等待关闭对话框。真的不好的事情可能发生,如果其他窗口没有被禁用。就像用户可以再次启动模式对话框一样,现在您的代码嵌套了两次。或者她可以关闭对话框的所有者窗口,现在它突然消失。



这些是如果您调用Application.DoEvents时遇到的确切类型的问题( )在一个循环内。哪种方式可以让表单在不禁用其他窗口的情况下表现模态。例如:

  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事件以知道它即将关闭:

  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;
//用< frm>做些事情
// ...
}


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...

Image 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.

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();
    }

This is dangerous.

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编程 - Modal和Non-Modal形成问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆