Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#Winform上使用Show对话框时出现非常奇怪的错误_C#_Winforms_Dialog_Modal Dialog - Fatal编程技术网

在C#Winform上使用Show对话框时出现非常奇怪的错误

在C#Winform上使用Show对话框时出现非常奇怪的错误,c#,winforms,dialog,modal-dialog,C#,Winforms,Dialog,Modal Dialog,我在VS Studio 2008 Express Edition中创建了两个表单,并在main program.cs文件中使用public static声明它们 我只想使用ShowDialog和Close在两个窗体之间切换,但当尝试关闭第二个窗体并使用ShowDialog再次打开第一个窗体时,它会说当窗体已可见时,我无法使用ShowDialog,而事实并非如此,因为我之前关闭了它以显示第二个窗体 它要求我在使用showdialog之前将FormVisible属性设置为false,所以我这样做了

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

我只想使用ShowDialog和Close在两个窗体之间切换,但当尝试关闭第二个窗体并使用ShowDialog再次打开第一个窗体时,它会说当窗体已可见时,我无法使用ShowDialog,而事实并非如此,因为我之前关闭了它以显示第二个窗体

它要求我在使用showdialog之前将FormVisible属性设置为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打开了

这是我的程序中的错误还是Winform中的错误

更新:这是我在第五个答案中发布的全部代码(我想使用showdialog而不是show,因为我可能在后台有一个我不想让用户访问的第三个表单):


我按照建议尝试了隐藏,但也不起作用。这是整个程序,我想做的很简单:我有两个表单,最初是在程序中创建的,每个表单上有一个按钮,用于关闭self和打开另一个表单。我将所有逻辑放在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();
          }
      }
  }
使用系统;
使用System.Windows.Forms;
命名空间两种形式
{
静态类程序
{
/// 
///应用程序的主要入口点。
/// 
/// 
公共静态表格1表格1;
公共静态表格2表格2;
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1=新Form1();
Form2=新的Form2();
Form1.ShowDialog();
Application.Run();
}
//从Form1按钮调用
内部静态无效显示表格2(表格1表格1)
{
Form1.Hide();
Form2.ShowDialog();
}
//从Form2按钮调用
内部静态空隙显示表格1(表格2表格2)
{
Form2.Hide();
Form1.ShowDialog();
}
}
}

尝试使用Hide()而不是Close()。我过去也遇到过类似的问题,Hide()对我有效。

查看
Close
Hide
之间的区别。以及
Show
ShowDialog
之间的区别

我真的不清楚你想要实现什么;您只(部分)描述了您在代码中所做的事情以及您遇到的问题的症状。你能描述一下你想做什么吗

如果您的目标是在主窗口中显示两个对话框,其中两个对话框中只有一个可以同时显示,那么可能有比使用两个静态(=全局)公共
表单
实例更好的解决方案,您可以使用
ShowDialog
显示这两个实例


您是否想过为此使用一个对话框
表单
,根据情况改变其外观?

这是您程序中的一个错误。当一个表单有两个实例(分别称为a和B)时,显然无法使用ShowDialog连续显示其中一个实例。如果你能做到这一点,就意味着A以模态方式显示B,然后B以模态方式显示A,然后A以模态方式显示B,等等。这就像是用两块砖建造一座房子,你只需不断地取下底部的砖,然后把它放在另一块砖上

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


静态表单几乎总是一个坏主意(我对“几乎”很客气)。如果您的表单需要很长时间才能创建,那么您应该确定哪些资源需要很长时间才能加载并缓存为静态对象,而不是试图将整个表单缓存为静态对象。

我认为您应该将模态对话框视为方法调用,并尝试使用调用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)按钮。

这是来自MSDN:

当窗体显示为模式时 对话框中,单击“关闭”按钮 (按钮底部带有X。) 表单右上角)原因 要隐藏的形式和 要设置为的DialogResult属性 DialogResult.Cancel.与无模式不同 窗体,则不调用Close方法 当用户 单击菜单的“关闭窗体”按钮 对话框或设置 DialogResult属性。而不是 表单被隐藏,可以再次显示 而不创建 对话框。因为显示了一个窗体 由于对话框未关闭,您可以 必须调用的Dispose方法 不再需要表单时的表单 根据你的申请

所以,一旦您使用ShowDialog显示表单,并且现在想要关闭它,只需让它返回DialogResult即可。取消 这将隐藏(它仍在内存中)您的第一个窗体。现在您可以在第二个窗体上调用ShowDialog。如果您想切换到第一个窗体,请再次执行此操作
[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;
                } 
            }

        }

    }