Very strange bug when using Show Dialog on C# Winform

天涯浪子 提交于 2019-11-30 15:52:30

This is from MSDN:

When a form is displayed as a modal dialog box, clicking the Close button (the button with an X at the upper-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.Cancel. Unlike modeless forms, the Close method is not called by the .NET Framework when the user clicks the close form button of a dialog box or sets the value of the DialogResult property. Instead the form is hidden and can be shown again without creating a new instance of the dialog box. Because a form displayed as a dialog box is not closed, you must call the Dispose method of the form when the form is no longer needed by your application.

So once you show a form using ShowDialog and you now want to close it, just let it return DialogResult.Cancel This will hide (it will still be in memory) your first form. Now you can call ShowDialog on your second form. Again, if you want to switch to first form then let the second form return DialogResult.Cancel and now just call ShowDialog on first form.

This is a bug in your program. When you have two instances of a form (call them A and B), you obviously cannot continually show one from the other using ShowDialog. If you could do this, it would mean that A shows B modally, and B then shows A modally, and A then shows B modally etc. This would be like building a house with two bricks, where you just keep taking the bottom brick and placing it on top of the other.

Your best solution is to not make these forms static, and instead just create new instances of each form as you need them. Your second-best solution is to use Show instead of ShowDialog; if you only have one of these forms showing at a time anyway, ShowDialog has no purpose.

Static forms are almost always a bad idea (and I'm being polite about "almost"). If your forms are taking a long time to create, you should identify what resource is taking so long to load and cache that as a static object, instead of trying to cache the entire form as static.

Try to use Hide() instead of Close(). I had a similar problem in the past and Hide() worked for me.

I think you should really treat Modal dialogs like method calls, and try to use the result of the Call to ShowDialog to determine what you want to do next? if you have a requirement to switch between dialogs you should use some sort of result (Maybe simply DialogResult see my example) or a public property of the dialog to determine if you need to Show another dialog, If you need to call one modal dialog from another you should think of it like a stack of forms, that effectively (even if you do make one invisible before calling another) place one upon the other. You really want to minimise this stacking of forms.

This is a bit of a contrived example but each form here simply has a single button with DialogResult set to OK.

[STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        bool exit = false;
        while (true)
        {
            if (exit) break;
            using (Form1 frm = new Form1())
            {
                switch(frm.ShowDialog())
                {
                    case DialogResult.OK:
                        break;
                    default:
                        exit = true;
                        break;
                }   
            }
            if(exit) break;
            using (Form2 frm = new Form2())
            {
                switch(frm.ShowDialog())
                {
                    case DialogResult.OK:
                        break;
                    default:
                        exit = true;
                        break;
                } 
            }

        }

    }

to exit simply click the red close (x) button.

Check out the difference between Close and Hide. And the difference between Show and ShowDialog.

It's not really clear to me what you want to achieve; you only (partially) describe what you done in code and the symptom of the problem you are having. Could you please describe what you are trying to do?

If your goal is to have two dialogs showing from your main window where only one of the two can be visible at the same time, then there are perhaps better solutions than using two static (=global) public Form instances that you show using ShowDialog.

Have you thought of using one dialog Form for this that just changes it appearance depending on the situation?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!