在C#Winform上使用Show Dialog时非常奇怪的错误

pro*_*ice 4 c# dialog modal-dialog winforms

我在VS Studio 2008 Express Edition中创建了2个表单,并在main program.cs文件中使用public static声明它们

我只是想用ShowDialog和Close在两个表单之间切换,但是当试图关闭第二个表单并再次使用showdialog打开第一个表单时,它表示当表单已经可见时我不能使用showDialog,而事实并非如此在显示第二种形式之前关闭它.

它让我在使用showdialog之前将form visible属性设置为false,所以我做到了

    internal static void CloseSecondForm(FirstForm FirstForm)
    {
        FirstForm .Close();
        SecondForm.Visible = false;
        SecondForm.ShowDialog();
    }
Run Code Online (Sandbox Code Playgroud)

但后来它说我不能使用ShowDialog,因为表格已经在对话模式中显示,我必须关闭它.所以我做了它所要求的

    internal static void CloseSecondForm(FirstForm FirstForm)
    {
        FirstForm .Close();
        SecondForm.Visible = false;
        SecondForm.Close();
        SecondForm.ShowDialog();
    }
Run Code Online (Sandbox Code Playgroud)

但它仍然假装表格已经用ShowDialog打开了!

这是我的编程或Winform中的Bug吗?

更新:这是我在第5个答案中发布的整个代码(我想使用showdialog而不是show,因为我可能在后台有第3个表单,我不希望用户访问):

  [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();
  }
Run Code Online (Sandbox Code Playgroud)

我按照建议使用了Hide,但它也没有用.这是整个程序,我想要做的很简单:我有两个最初在程序中创建的表单,每个表单上有一个按钮关闭自己并打开另一个.我将所有逻辑放在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();
          }
      }
  }
Run Code Online (Sandbox Code Playgroud)

Mus*_*sis 5

这是您程序中的错误.当你有一个表单的两个实例(称为A和B)时,你显然不能使用ShowDialog连续显示另一个.如果你能做到这一点,那就意味着A显示B模态,然后B然后显示A模态,然后A然后显示模态B等.这就像建造一个有两块砖的房子,你只需要继续使用底砖和把它放在另一个上面.

您最好的解决方案是不要将这些表单设置为静态,而只是根据需要创建每个表单的新实例.您的第二个最佳解决方案是使用Show而不是ShowDialog; 如果你一次只显示其中一个表格,ShowDialog没有任何意义.

静态形式几乎总是一个坏主意(而且我对"差不多"很有礼貌).如果您的表单需要很长时间才能创建,那么您应该确定加载和缓存该资源需要花费多长时间作为静态对象,而不是尝试将整个表单缓存为静态.

  • 理解这个问题的关键是ShowDialog是一个阻塞调用,这意味着按钮处理程序永远无法完成,窗口永远不会完成关闭.如果ShowDialog不是VBA中的阻塞调用,那么我的记忆必须离开我. (3认同)

P.K*_*P.K 5

这是从MSDN:

当窗体显示为模式对话框时,单击“关闭”按钮(窗体右上角带有X的按钮)将导致窗体被隐藏,并且DialogResult属性被设置为DialogResult.Cancel。与无模式窗体不同,当用户单击对话框的关闭窗体按钮或设置DialogResult属性的值时,.NET Framework不会调用Close方法。而是隐藏该窗体,并且可以在不创建对话框的新实例的情况下再次显示该窗体。因为未关闭显示为对话框的表单,所以当应用程序不再需要该表单时,必须调用该表单的Dispose方法。

因此,一旦使用ShowDialog显示表单并现在要关闭它,只需让它返回DialogResult.Cancel即可隐藏(仍保留在内存中)您的第一个表单。现在,您可以在第二个窗体上调用ShowDialog。同样,如果要切换到第一个窗体,则让第二个窗体返回DialogResult.Cancel,现在只需在第一个窗体上调用ShowDialog。