C# WinForms启动(闪屏)窗体未隐藏

10

我有一个WinForms应用程序,其中使用了2个窗体来显示所有必要的控件。第一个窗体是启动屏幕,在其中告诉用户正在加载等待。所以我使用以下代码:

Application.Run( new SplashForm() );

当应用程序加载完毕后,我希望SplashForm隐藏或放到后面,并显示主窗体。我目前正在使用以下代码:

private void showMainForm()
{
    this.Hide();
    this.SendToBack();

    // Show the GUI
    mainForm.Show();
    mainForm.BringToFront();
}

我看到的是MainForm已经显示出来,但SplashForm仍然在最上层。目前我的做法是手动点击MainForm将其置于最前面。有关这种情况发生的任何想法吗?

4个回答

23

可能你只是想关闭启动窗体,而不是将其发送到后面。

我在一个单独的线程上运行启动窗体(这是SplashForm类):

class SplashForm
{
    //Delegate for cross thread call to close
    private delegate void CloseDelegate();

    //The type of form to be displayed as the splash screen.
    private static SplashForm splashForm;

    static public void ShowSplashScreen()
    {
        // Make sure it is only launched once.

        if (splashForm != null)
            return;
        Thread thread = new Thread(new ThreadStart(SplashForm.ShowForm));
        thread.IsBackground = true;
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();           
    }

    static private void ShowForm()
    {
        splashForm = new SplashForm();
        Application.Run(splashForm);
    }

    static public void CloseForm()
    {
        splashForm.Invoke(new CloseDelegate(SplashForm.CloseFormInternal));
    }

    static private void CloseFormInternal()
    {
        splashForm.Close();
        splashForm = null;
    }
...
}

而主程序函数看起来像这样:

[STAThread]
static void Main(string[] args)
{
    SplashForm.ShowSplashScreen();
    MainForm mainForm = new MainForm(); //this takes ages
    SplashForm.CloseForm();
    Application.Run(mainForm);
}

1
抱歉,我只在WinForms中使用它。 - Grzenio
我在你的类中定义了一个变量,比如“frmSplash splashForm”,但是我遇到了一些错误,比如“需要非静态字段、方法或属性的对象引用”错误,这个定义变量怎么使用? - Sadegh
我遇到了一个奇怪的问题,我的启动画面没有在单独的线程中,在Win7中运行良好,但在XP中它仍然被其他东西覆盖,尽管使用了 BringToFront() 方法。我添加了上面的代码将其放入自己的线程中,现在它的行为符合预期!因此,谢谢。 - Quinxy von Besiex

5
这非常重要,可以防止启动画面在关闭后抢占焦点并将主窗体推到后台:
protected override bool ShowWithoutActivation {
    get { return true; }
}

将以下内容添加到您的启动画面表单类中。

感谢分享这有用的信息 :) - hima

2
如果我理解得正确,你应该在主窗体上使用Application.Run。因此,只需使用类似以下代码显示你的启动画面即可:
```vb.net Application.Run(new SplashScreen()); ```
请注意,这里的SplashScreen是你自己创建的启动画面窗体类名。
using(MySplash form = new MySplash())
   form.ShowDialog();

在你想要关闭它时,可以在MySplash中手动关闭。

或者在主窗体的Load事件处理程序中显示它,然后等待它关闭或者在Load方法完成之前进行其他操作。可能需要在显示之前将Visible设置为false,并在之后设置为true。


1

我相信我的当前设计可能存在设计缺陷!

我认为实现我所需的最佳方式是让所有东西从主窗体(MainForm)控制。这样我就可以使用:

Application.Run(new MainForm());

这将负责显示/更新/隐藏启动屏幕。这样,我就可以通过主窗体来管理与系统其余部分的必要复杂交互。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接