如何关闭两个窗体并在新线程打开新窗体?战舰应用开发问题
解决战舰应用主窗口无法关闭的问题
嘿,我来帮你搞定这个问题!看起来你遇到的核心问题是主窗口Form1没法在选择游戏模式后关闭,对吧?这大概率是因为Form1是你的应用启动窗口(也就是Program.cs里Application.Run(new Form1())的那个),直接关闭它会默认终止整个应用进程,导致你刚打开的Form2也跟着退出。下面给你几个可行的解决思路:
方案一:修改启动逻辑,让Form2成为新的主窗口
这个方案的核心是取消Form1关闭时的默认应用退出行为,转而启动Form2作为新的主窗口来维持应用运行:
- 在Form3的模式确认按钮点击事件中,先记录选中的模式,关闭Form3并触发Form1的关闭:
private void btnConfirmMode_Click(object sender, EventArgs e) { // 记录选中的游戏模式(可以用静态变量或参数传递给Form2) GameSettings.SelectedMode = cbMode.SelectedItem.ToString(); // 关闭当前的模式选择窗口Form3 this.Close(); // 找到主窗口Form1并触发关闭 foreach (Form form in Application.OpenForms) { if (form is Form1 mainForm) { mainForm.Close(); break; } } }
- 在Form1的
FormClosing事件中,拦截默认的应用退出行为,启动Form2后再彻底释放Form1:
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // 取消默认的应用终止逻辑 e.Cancel = true; // 启动新线程运行Form2(WinForms必须使用STA线程) Thread gameThread = new Thread(() => { Application.Run(new Form2(GameSettings.SelectedMode)); }); gameThread.SetApartmentState(ApartmentState.STA); gameThread.Start(); // 彻底释放Form1资源,此时原消息循环结束,但新线程的消息循环会维持应用运行 this.Dispose(); }
方案二:隐藏Form1而非直接关闭(适合快速适配)
如果不想改动启动逻辑,可以先隐藏Form1,关闭Form3后启动Form2,等Form2退出时再关闭Form1:
private void btnConfirmMode_Click(object sender, EventArgs e) { string selectedMode = cbMode.SelectedItem.ToString(); // 找到并隐藏主窗口Form1 Form1 mainForm = Application.OpenForms.OfType<Form1>().FirstOrDefault(); mainForm?.Hide(); // 关闭模式选择窗口Form3 this.Close(); // 启动Form2的线程 Thread gameThread = new Thread(() => { Form2 gameForm = new Form2(selectedMode); // 当Form2关闭时,彻底关闭Form1 gameForm.FormClosed += (s, args) => mainForm?.Close(); Application.Run(gameForm); }); gameThread.SetApartmentState(ApartmentState.STA); gameThread.Start(); }
关键注意点
- WinForms的UI控件必须在STA线程中创建和运行,所以启动Form2的线程一定要设置
ApartmentState.STA,否则会出现控件渲染异常或功能失效的问题。 - 传递游戏模式时,可以用静态类存储、构造函数参数传递等方式,根据你的代码结构选择最方便的方式。
内容的提问来源于stack exchange,提问作者Nesox
相关产品推荐
相关产品推荐

