我编写C#窗体程序时遇到了这个问题:在一个窗体的代码中new另外一个窗体的实例,但是运行该窗体后,一旦关闭窗体,其生成的窗体也跟着关闭。怎样才能使这样由别的窗体生成的新窗体不因其前序窗体的关闭而关闭?

解决方案 »

  1.   

    这样做有点技术难度。如果要从一个窗体形成另一个窗体的实例,这两个窗体实际上供用一个线程,当你关闭前一个窗体时,该线程也随之关闭,故后一个窗体也关闭。如果你希望关闭前一个窗体时,继续保持后一个窗体,就必须用多线程。你最好在项目的program文件里面进行多线程编程试试,这个方面我做得也不多。我一般都是先创建一个MDI窗体,再添加MDI子窗体。这样在主窗体不关闭的情况下,其他的子窗体都可以自由开关。
      

  2.   

    参考一下这个吧
    运行Forms类的NewForm()就是新窗口
     public class Forms
        {
            // 这是一个内部集合,用来管理文件窗体(MainForm)的清单。
            // 其它的窗体(例如:About)不会位于此清单中。
            private static Collection<MainForm> m_Forms = new Collection<MainForm>();        // 这是一个内部的计数器,用于替每一个新建立窗体的标题尾端加上一个数目字。
            private static int m_FormsCreated = 0;        // 当询问用户是否要保存一个内容已变更的文件时,
            // 如果用户按下“取消”按钮,将使用此属性来判断
            // 我们是否需要停止应用程序关闭。
            private static bool m_CancelExit = false;        // 此属性用来检查关闭目前是否正在进行中。
            private static bool m_ShutdownInProgress = false;        // 目前已加载之窗体的数目。
            public static int Count
            {
                get
                {
                    return m_Forms.Count;
                }
            }        // 这是本应用程序的进入点。
            [STAThread]
            public static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);            // 开启第一个文件窗口。
                try
                {
                    Forms.NewForm();
                }
                catch (Exception)
                {
                    // 表示有错误发生。
                    MessageBox.Show("非常抱歉,我们无法加载一个文件。再会!",
                        "应用程序主要进入点", MessageBoxButtons.OK, MessageBoxIcon.Error);                // 通知所有必须结束的讯息帮浦,接着在讯息处理完成之后关闭所有应用程序窗口。
                    Application.Exit();
                }            // 设定主执行绪执行于特定窗体的控制之外,
                // 如此一来,关闭某一个文件并不会结束整个处理序。
                Application.Run();
            }        public static void NewForm()
            {
                try
                {
                    Forms.m_FormsCreated += 1;                MainForm frm = new MainForm();                frm.Text = "文件" + Forms.m_FormsCreated.ToString();                // 将窗体(文件窗口)加入至内部集合中。
                    m_Forms.Add(frm);                // 设定当引发窗体(文件窗口)的 Closed 事件时便执行事件处理例程 MainForm_Closed,
                    // 以便让我们知道使用者关闭了文件窗口。
                    frm.Closed += new System.EventHandler(Forms.MainForm_Closed);                // 设定当引发自订的 SaveWhileClosingCancelled 事件时便执行事件处理
                    // 例程 MainForm_SaveWhileClosingCancelled,以便让我们知道当询问使
                    // 用者是否要储存已变更的文件时,使用者是否按下「取消」按钮。
                    frm.SaveWhileClosingCancelled += new System.EventHandler(Forms.MainForm_SaveWhileClosingCancelled);                // 设定当引发自订的 ExitApplicaiton 事件时便执行事件处理例程 MainForm_ExitApplication,
                    // 以便让我们知道使用者在某一个文件窗口中从「档案」菜单中选取「结束」指令来结束应用程序。
                    frm.ExitApplication += new System.EventHandler(Forms.MainForm_ExitApplication);                // 使窗体成为可见的。
                    frm.Show();
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message, exp.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);                if (Forms.Count == 0)
                    {
                        // 再次将错误掷回给 Main() 程序,如此一来我们就能够结束处理序。
                        throw exp;
                    }
                }
            }        private static void FormClosed(MainForm frm)
            {
                // 从内部集合中移除已关闭的窗体(文件窗口)。
                m_Forms.Remove(frm);            // 如果不存在其它已开启的窗体(文件窗口),就结束应用程序。
                if (m_Forms.Count == 0)
                {
                    Application.Exit();
                }
            }        public static void ExitApp()
            {
                try
                {
                    m_ShutdownInProgress = true;                MainForm frm;
                    int i;                // 循环处理内部集合,每一次向后处理一个窗体(文件窗口),要求每一个
                    // 窗体(文件窗口)去关闭它自己。只会要求文件内容已更改的窗体(文件
                    // 窗口)去关闭它自己,但是如果使用者按下「取消」按钮,我们就会停止 
                    // 去关闭任何已开启的窗体(文件窗口),当然也就不会结束应用程序。
                    for (i = m_Forms.Count - 1; i >= 0; i--)
                    {
                        frm = (MainForm)(m_Forms[i]);                    if (frm.Dirty)
                        {
                            frm.Close();
                        }                    // 如果 m_CancelExit 的值为 True,表示使用者按下「取消」
                        // 按钮,所以此时应该跳离本程序并停止结束应用程序。
                        if (m_CancelExit == true)
                        {
                            m_CancelExit = false;
                            return;
                        }
                    }                // 现在我们要关闭所有内容并未更改的文件窗口,
                    // 此时,没有任何窗口能够停止应用程序的结束作业。
                    if (m_Forms.Count > 0)
                    {
                        for (i = m_Forms.Count - 1; i >= 0; i--)
                        {
                            frm = (MainForm)(m_Forms[i]);
                            frm.Close();
                        }
                    }
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message, exp.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
                finally
                {
                    m_ShutdownInProgress = false;
                }
            }        private static void MainForm_Closed(object sender, System.EventArgs e)
            {
                try
                {
                    // 当一个文件窗口完成关闭后就会引发此事件。
                    MainForm frm = (MainForm)(sender);                // 移除事件与事件处理例程之间的关联,这些关联是文件窗口在建立时所指定的。
                    frm.Closed -= new System.EventHandler(Forms.MainForm_Closed);
                    frm.SaveWhileClosingCancelled -= new System.EventHandler(Forms.MainForm_SaveWhileClosingCancelled);
                    frm.ExitApplication -= new System.EventHandler(Forms.MainForm_ExitApplication);                // 呼叫我们的函式来完成清理作业。
                    Forms.FormClosed(frm);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message, exp.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        private static void MainForm_SaveWhileClosingCancelled(object sender, System.EventArgs e)
            {
                // 当询问使用者是否要储存一个内容已变更的文件时,如果使用者按下「取消」按钮,
                // 将会引发 SaveWhileClosingCancelled 事件并执行此事件处理例程。
                if (m_ShutdownInProgress)
                {
                    // 如果我们确实处于关闭过程中,只需要更改我们的内部值即可。
                    Forms.m_CancelExit = true;
                }
            }        private static void MainForm_ExitApplication(object sender, System.EventArgs e)
            {
                // 如果使用者从「档案」菜单中选取「结束」指令
                // 将会引发 ExitApplication 事件并执行此事件处理例程。
                Forms.ExitApp();
            }    }
      

  3.   

    参考一下这个吧
    运行Forms类的NewForm()就是新窗口
     public class Forms
        {
            // 这是一个内部集合,用来管理文件窗体(MainForm)的清单。
            // 其它的窗体(例如:About)不会位于此清单中。
            private static Collection<MainForm> m_Forms = new Collection<MainForm>();        // 这是一个内部的计数器,用于替每一个新建立窗体的标题尾端加上一个数目字。
            private static int m_FormsCreated = 0;        // 当询问用户是否要保存一个内容已变更的文件时,
            // 如果用户按下“取消”按钮,将使用此属性来判断
            // 我们是否需要停止应用程序关闭。
            private static bool m_CancelExit = false;        // 此属性用来检查关闭目前是否正在进行中。
            private static bool m_ShutdownInProgress = false;        // 目前已加载之窗体的数目。
            public static int Count
            {
                get
                {
                    return m_Forms.Count;
                }
            }        // 这是本应用程序的进入点。
            [STAThread]
            public static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);            // 开启第一个文件窗口。
                try
                {
                    Forms.NewForm();
                }
                catch (Exception)
                {
                    // 表示有错误发生。
                    MessageBox.Show("非常抱歉,我们无法加载一个文件。再会!",
                        "应用程序主要进入点", MessageBoxButtons.OK, MessageBoxIcon.Error);                // 通知所有必须结束的讯息帮浦,接着在讯息处理完成之后关闭所有应用程序窗口。
                    Application.Exit();
                }            // 设定主执行绪执行于特定窗体的控制之外,
                // 如此一来,关闭某一个文件并不会结束整个处理序。
                Application.Run();
            }        public static void NewForm()
            {
                try
                {
                    Forms.m_FormsCreated += 1;                MainForm frm = new MainForm();                frm.Text = "文件" + Forms.m_FormsCreated.ToString();                // 将窗体(文件窗口)加入至内部集合中。
                    m_Forms.Add(frm);                // 设定当引发窗体(文件窗口)的 Closed 事件时便执行事件处理例程 MainForm_Closed,
                    // 以便让我们知道使用者关闭了文件窗口。
                    frm.Closed += new System.EventHandler(Forms.MainForm_Closed);                // 设定当引发自订的 SaveWhileClosingCancelled 事件时便执行事件处理
                    // 例程 MainForm_SaveWhileClosingCancelled,以便让我们知道当询问使
                    // 用者是否要储存已变更的文件时,使用者是否按下「取消」按钮。
                    frm.SaveWhileClosingCancelled += new System.EventHandler(Forms.MainForm_SaveWhileClosingCancelled);                // 设定当引发自订的 ExitApplicaiton 事件时便执行事件处理例程 MainForm_ExitApplication,
                    // 以便让我们知道使用者在某一个文件窗口中从「档案」菜单中选取「结束」指令来结束应用程序。
                    frm.ExitApplication += new System.EventHandler(Forms.MainForm_ExitApplication);                // 使窗体成为可见的。
                    frm.Show();
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message, exp.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);                if (Forms.Count == 0)
                    {
                        // 再次将错误掷回给 Main() 程序,如此一来我们就能够结束处理序。
                        throw exp;
                    }
                }
            }        private static void FormClosed(MainForm frm)
            {
                // 从内部集合中移除已关闭的窗体(文件窗口)。
                m_Forms.Remove(frm);            // 如果不存在其它已开启的窗体(文件窗口),就结束应用程序。
                if (m_Forms.Count == 0)
                {
                    Application.Exit();
                }
            }        public static void ExitApp()
            {
                try
                {
                    m_ShutdownInProgress = true;                MainForm frm;
                    int i;                // 循环处理内部集合,每一次向后处理一个窗体(文件窗口),要求每一个
                    // 窗体(文件窗口)去关闭它自己。只会要求文件内容已更改的窗体(文件
                    // 窗口)去关闭它自己,但是如果使用者按下「取消」按钮,我们就会停止 
                    // 去关闭任何已开启的窗体(文件窗口),当然也就不会结束应用程序。
                    for (i = m_Forms.Count - 1; i >= 0; i--)
                    {
                        frm = (MainForm)(m_Forms[i]);                    if (frm.Dirty)
                        {
                            frm.Close();
                        }                    // 如果 m_CancelExit 的值为 True,表示使用者按下「取消」
                        // 按钮,所以此时应该跳离本程序并停止结束应用程序。
                        if (m_CancelExit == true)
                        {
                            m_CancelExit = false;
                            return;
                        }
                    }                // 现在我们要关闭所有内容并未更改的文件窗口,
                    // 此时,没有任何窗口能够停止应用程序的结束作业。
                    if (m_Forms.Count > 0)
                    {
                        for (i = m_Forms.Count - 1; i >= 0; i--)
                        {
                            frm = (MainForm)(m_Forms[i]);
                            frm.Close();
                        }
                    }
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message, exp.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
                finally
                {
                    m_ShutdownInProgress = false;
                }
            }        private static void MainForm_Closed(object sender, System.EventArgs e)
            {
                try
                {
                    // 当一个文件窗口完成关闭后就会引发此事件。
                    MainForm frm = (MainForm)(sender);                // 移除事件与事件处理例程之间的关联,这些关联是文件窗口在建立时所指定的。
                    frm.Closed -= new System.EventHandler(Forms.MainForm_Closed);
                    frm.SaveWhileClosingCancelled -= new System.EventHandler(Forms.MainForm_SaveWhileClosingCancelled);
                    frm.ExitApplication -= new System.EventHandler(Forms.MainForm_ExitApplication);                // 呼叫我们的函式来完成清理作业。
                    Forms.FormClosed(frm);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message, exp.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        private static void MainForm_SaveWhileClosingCancelled(object sender, System.EventArgs e)
            {
                // 当询问使用者是否要储存一个内容已变更的文件时,如果使用者按下「取消」按钮,
                // 将会引发 SaveWhileClosingCancelled 事件并执行此事件处理例程。
                if (m_ShutdownInProgress)
                {
                    // 如果我们确实处于关闭过程中,只需要更改我们的内部值即可。
                    Forms.m_CancelExit = true;
                }
            }        private static void MainForm_ExitApplication(object sender, System.EventArgs e)
            {
                // 如果使用者从「档案」菜单中选取「结束」指令
                // 将会引发 ExitApplication 事件并执行此事件处理例程。
                Forms.ExitApp();
            }    }
      

  4.   

    你可以隐藏前一个窗口啊, 以前VB 就是这么做的, 另外, 你在一开始的Main 线程 (program.cs)中逐个载入Form,
      

  5.   

    eternalolin 
    olin 
    等 级:
     发表于:2008-02-09 16:20:324楼 得分:0 
    我也是这样想的,但是生成的窗体关闭后原窗体还是隐藏状态,怎么解决? 
     
    这个也简单呀,可以在关闭事件中加入显示原窗体的语句