简体   繁体   English

Windows Forms 启动画面 - 在加载主表单时显示一个表单

[英]Windows Forms Splash Screen - Show a form while loading main form

I am trying to make the splash screen appears first and after the splash, the MainForm appears.我试图让启动画面首先出现,然后在启动之后出现MainForm But the progress bar which I have in splash screen don't get to the end of the bar.但是我在初始屏幕中的进度条没有到达进度条的末尾。 And the program continues running and not works.并且程序继续运行并且不起作用。

How can I show the splash screen during loading the main form?如何在加载主表单时显示启动画面?

My code It's something like that:我的代码是这样的:

public partial class SplashForm : Form
{
    public SplashForm()
    { 
        InitializeComponent();
    }
    private void SplashForm_Load(object sender, EventArgs e)
    {
        timer1.Enabled = true;
        timer1.Start();
        timer1.Interval = 1000;
        progressBar1.Maximum = 10;
        timer1.Tick += new EventHandler(timer1_Tick);
    }
    public void timer1_Tick(object sender, EventArgs e)
    {
        if (progressBar1.Value != 10)
        {
            progressBar1.Value++;
        }
        else
        {
            timer1.Stop();
            Application.Exit();
        }
    }     
}

Here are the first part of the code of the MainForm :这是MainForm代码的第一部分:

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        Application.Run(new SplashForm());
    }
}

There are different ways of creating splash screens:有多种创建启动画面的方法:

  • You can rely on the splash screen feature of WindowsFormsApplicationBase您可以依赖WindowsFormsApplicationBase的启动画面功能

  • You can show implement the feature yourself by showing a form on a different UI thread and hiding it after the main from loaded successfully.您可以通过在不同的 UI 线程上显示一个表单并在 main 成功加载后隐藏它来展示自己实现该功能。

In this post I'll show an example of both solutions.在这篇文章中,我将展示这两种解决方案的示例。

Note: Those who are looking for showing a loading window or a loading gif animation during loading of data, can take a look at this post: Show Loading animation during loading data in other thread注意:那些正在寻找在加载数据期间显示加载窗口或加载 gif 动画的人,可以看一下这篇文章:在其他线程中加载数据期间显示加载动画

Option 1 - Use WindowsFormsApplicationBase Splash Screen feature选项 1 - 使用 WindowsFormsApplicationBase 启动画面功能

  1. Add a reference of Microsoft.VisualBasic.dll to your project.Microsoft.VisualBasic.dll的引用添加到您的项目中。
  2. Create a MyApplication class by deriving from WindowsFormsApplicationBase通过派生自WindowsFormsApplicationBase创建MyApplication
  3. override OnCreateMainForm and assign the from that you want to be the startup form to MainForm property.覆盖OnCreateMainForm并将您想要作为启动表单的 from 分配给MainForm属性。
  4. Override OnCreateSplashScreen and assign the form that you want to show as splash screen to SplashScreen property.覆盖OnCreateSplashScreen并将要显示为初始屏幕的表单分配给SplashScreen属性。

  5. In your Main method, create an instance of MyApplication and call its Run method.Main方法中,创建MyApplication的实例并调用其Run方法。

Example例子

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        var app = new MyApplication();
        app.Run(Environment.GetCommandLineArgs());
    }
}
public class MyApplication : WindowsFormsApplicationBase
{
    protected override void OnCreateMainForm()
    {
        MainForm = new YourMainForm();
    }
    protected override void OnCreateSplashScreen()
    {
        SplashScreen = new YourSplashForm();
    }
}

Option 2 - Implement the feature using a different UI thread选项 2 - 使用不同的 UI 线程实现该功能

You can implement the feature yourself by showing the splash screen in a different UI thread.您可以通过在不同的 UI 线程中显示启动画面来自己实现该功能。 To do so, you can subscribe to Load event of the main form in Program class, and show and close your splash screen there.为此,您可以在Program类中订阅主窗体的Load事件,并在那里显示和关闭启动画面。

Example例子

using System;
using System.Threading;
using System.Windows.Forms;

static class Program
{
    static Form SplashScreen;
    static Form MainForm;
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        //Show Splash Form
        SplashScreen = new Form();
        var splashThread = new Thread(new ThreadStart(
            () => Application.Run(SplashScreen)));
        splashThread.SetApartmentState(ApartmentState.STA);
        splashThread.Start();

        //Create and Show Main Form
        MainForm = new Form8();
        MainForm.Load += MainForm_LoadCompleted;
        Application.Run(MainForm);
    }
    private static void MainForm_LoadCompleted(object sender, EventArgs e)
    {
        if (SplashScreen != null && !SplashScreen.Disposing && !SplashScreen.IsDisposed)
            SplashScreen.Invoke(new Action(() => SplashScreen.Close()));
        MainForm.TopMost = true;
        MainForm.Activate();
        MainForm.TopMost = false;
    }
}

Note: To show a smooth edge custom shaped splash screen take a look at this post: Windows Forms Transparent Background Image .注意:要显示平滑边缘的自定义形状闪屏,请查看这篇文章: Windows 窗体透明背景图像

I have had a splash in my Winforms application for years.多年来,我的 Winforms 应用程序一直备受瞩目。 The splash stays on for 5 seconds and is non-modal, but topmost.飞溅会持续 5 秒,并且是非模态的,但在最上面。 Initialisations keep running without issues.初始化继续运行没有问题。

In main program, I changed nothing在主程序中,我什么也没做

    [STAThread]
    static void Main()
    {
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FrmMain());
    }

    //---------------------------------------------------------------------

This is my splash, it has a timer that closes it after 5 seconds这是我的飞溅,它有一个 5 秒后关闭的计时器

    public partial class FrmSplash : Form
    {
      private Timer _timer;
      private int _cTick = 5;

      public FrmSplash()
      {
        InitializeComponent();
        _timer = new Timer() { Interval = 1000, Enabled = true };
        _timer.Tick += CTick;
      }

      private void CTick(object sender, EventArgs e)
      {
        if (--_cTick<0)
        {
            _timer.Enabled = false;
            Close();

        }
      }
   }

In the main form constructor, I call the splash followed by Application.DoEvents() so it will be shown on the screen, meanwhile my initialisations can proceed,在主窗体构造函数中,我调用了启动后跟 Application.DoEvents() 所以它会显示在屏幕上,同时我的初始化可以继续,

   //---------------------------------------------------------------------

   public FrmMain()
   {
      InitializeComponent();
      var  FrmSplash = new FrmSplash();
      FrmSplash.Show();
      Application.DoEvents();
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM