You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何关闭两个窗体并在新线程打开新窗体?战舰应用开发问题

解决战舰应用主窗口无法关闭的问题

嘿,我来帮你搞定这个问题!看起来你遇到的核心问题是主窗口Form1没法在选择游戏模式后关闭,对吧?这大概率是因为Form1是你的应用启动窗口(也就是Program.cs里Application.Run(new Form1())的那个),直接关闭它会默认终止整个应用进程,导致你刚打开的Form2也跟着退出。下面给你几个可行的解决思路:

方案一:修改启动逻辑,让Form2成为新的主窗口

这个方案的核心是取消Form1关闭时的默认应用退出行为,转而启动Form2作为新的主窗口来维持应用运行:

  1. 在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;
        }
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:52:47