在C#WinForm的使用显示对话框时,很奇怪的bug(Very strange bug when

2019-06-27 13:56发布

我在VS Studio 2008速成版创建的2种形式,并与主要的Program.cs文件公共静态声明它们

我只是想这两种形式与ShowDialog的和关闭,但之间切换试图关闭第二种形式与ShowDialog的它说当窗体已经可见,我不能使用的ShowDialog再次打开第一种形式,而这是不正确的,因为我的时候之前关闭它以显示第二种形式。

它要求我使用的ShowDialog之前设置窗体可见属性设置为false,所以我做到了

    internal static void CloseSecondForm(FirstForm FirstForm)
    {
        FirstForm .Close();
        SecondForm.Visible = false;
        SecondForm.ShowDialog();
    }

但随后说我不能使用,因为ShowDialog的形式在对话框模式已经显示出,而且我必须关闭它。 所以,我没有什么要求

    internal static void CloseSecondForm(FirstForm FirstForm)
    {
        FirstForm .Close();
        SecondForm.Visible = false;
        SecondForm.Close();
        SecondForm.ShowDialog();
    }

但它仍然假装形式已经与ShowDialog的开启!

这是我PROG或WinForm的一个Bug?

更新:这是整个代码我张贴在5个答案(我想用的ShowDialog并没有显示,因为我可以在后台第三形式,我不希望用户访问):

  [STAThread]
  static void Main()
  {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Form1 = new Form1();
      Form2 = new Form2();
      Form1.ShowDialog();
      Application.Run();

  }

  // called from Form1 BUTTON
  internal static void ShowForm2(Form1 Form1)
  {
      Form1.Hide();
      Form2.ShowDialog();
  }

  // called from Form2 BUTTON
  internal static void ShowForm1(Form2 Form2)
  {
      Form2.Hide();
      Form1.ShowDialog();
  }

我试图隐藏的建议,但它也不起作用。 这是整个计划,我想要做的是非常简单的:我最初计划,每个表单上一个键创建两种形式关闭自我和打开其他。 我把所有的逻辑在下面的Program.cs:

  using System;
  using System.Windows.Forms;

  namespace twoforms
  {
      static class Program
      {
          /// <summary>
          /// The main entry point for the application.
          /// </summary>
          /// 
          public static Form1 Form1;
          public static Form2 Form2;

          [STAThread]
          static void Main()
          {
              Application.EnableVisualStyles();
              Application.SetCompatibleTextRenderingDefault(false);
              Form1 = new Form1();
              Form2 = new Form2();
              Form1.ShowDialog();
              Application.Run();

          }

          // called from Form1 BUTTON
          internal static void ShowForm2(Form1 Form1)
          {
              Form1.Hide();
              Form2.ShowDialog();
          }

          // called from Form2 BUTTON
          internal static void ShowForm1(Form2 Form2)
          {
              Form2.Hide();
              Form1.ShowDialog();
          }
      }
  }

Answer 1:

这是从MSDN:

当窗体显示为模态对话框,点击关闭按钮(与窗体的右上角的X按钮)导致形式被隐藏和DialogResult属性被设置为DialogResult.Cancel。 不像无模式形式中,所述关闭方法并不由.NET Framework当用户点击一个对话框的关闭形式按钮或设置DialogResult属性的值调用。 相反,形式是隐藏的,可以再次显示,而无需创建对话框的新实例。 由于显示为一个对话框的形式不是封闭的,你必须调用形式的Dispose方法时,你的应用程序不再需要的形式。

所以一旦你表现出的形式使用ShowDialog的,而现在要关闭它,就让它返回DialogResult.Cancel这将隐藏(它仍然会在内存中)你的第一个形式。 现在,你可以调用的ShowDialog你的第二个形式。 同样,如果你想切换到第一种形式则让第二种形式返回DialogResult.Cancel现在只是调用ShowDialog的第一个形式。



Answer 2:

这是在你的程序中的错误。 当你有一个表单的两个实例(称他们为A和B),你显然不能持续显示一个从其它使用的ShowDialog。 如果你能做到这一点,那就意味着A显示乙模态,而B则显示了一个模态,而A则显示乙模态等。这就像盖房子用两块砖,在那里你只需继续服用底砖将其放置在另一个的顶部。

你最好的解决方案就是不要让这些形式静态的,因为你需要他们,而不是只建立各种形式的新实例。 你的第二个最好的解决方案是使用显示,而不是ShowDialog的; 如果你只有这些形式同时显示反正之一,ShowDialog的没有目的。

静态形式几乎总是一个坏主意(我礼貌约“几乎”)。 如果您的形式花费很长的时间来创建,你应该确定哪些资源需要这么长时间来加载和缓存,作为一个静态的对象,而不是试图缓存整个形式为静态。



Answer 3:

尝试使用隐藏(),而不是关闭()。 我在过去和隐藏(类似的问题)为我工作。



Answer 4:

我想你应该真心对待模式对话框类似的方法调用,并尝试使用该调用的结果ShowDialog的,以确定你下一步想做什么? 如果你有一个要求对话之间切换,你应该使用某种结果的(也许根本的DialogResult见我的例子),或在对话框的公共属性,以确定是否需要显示另一个对话框,如果你需要调用从一个模态对话框另外,你应该能够有效地把它想的表格纸叠,(即使你做调用另一个前一个无形的)放置在另一个上。 你真的要尽量减少这种形式堆叠。

这是一个有点人为的例子,但这里每个窗体只是具有的DialogResult设置为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;
                } 
            }

        }

    }

退出只需点击红色的关闭(X)按钮。



Answer 5:

退房的区别CloseHide 。 之间的差异ShowShowDialog

这不是真的我清楚你想要达到的目标; 你只(部分)描述你在代码中,你所遇到的问题的症状做了什么。 能否请你描述一下你想干什么?

如果你的目标是有两个对话框从主窗口中显示,其中只有两个人能在同一时间是可见的,那么还有比使用两个静态(=全球)公共也许是更好的解决方案Form的,你告诉使用实例ShowDialog

你有没有想过使用一个对话框的Form为这一点,只是改变视情况而定它的外观?



文章来源: Very strange bug when using Show Dialog on C# Winform