简体   繁体   English

如何在 windows 窗体应用程序中构建启动画面?

[英]How to build splash screen in windows forms application?

I need to show splash screen on my application start for few seconds.我需要在我的应用程序启动时显示启动画面几秒钟。 Does anybody know how to implement this?有谁知道如何实现这一点?

Will be much appreciate for the help.将不胜感激的帮助。

First, create your splash screen as a borderless, immovable form with your image on it, set to initially display at the center of the screen, colored the way you want.首先,将您的启动画面创建为无边界、不可移动的形式,上面有您的图像,设置为最初显示在屏幕中央,按您想要的方式着色。 All of this can be set from within the designer;所有这些都可以在设计器中进行设置; specifically, you want to:具体来说,您想要:

  • Set the form's ControlBox, MaximizeBox, MinimizeBox and ShowIcon properties to "False"将表单的 ControlBox、MaximizeBox、MinimizeBox 和 ShowIcon 属性设置为“False”
  • Set the StartPosition property to "CenterScreen"将 StartPosition 属性设置为“CenterScreen”
  • Set the FormBorderStyle property to "None"将 FormBorderStyle 属性设置为“无”
  • Set the form's MinimumSize and MaximumSize to be the same as its initial Size.将窗体的 MinimumSize 和 MaximumSize 设置为与其初始大小相同。

Then, you need to decide where to show it and where to dismiss it.然后,您需要决定在哪里显示它以及在哪里关闭它。 These two tasks need to occur on opposite sides of the main startup logic of your program.这两个任务需要在程序的主要启动逻辑的相反侧发生。 This could be in your application's main() routine, or possibly in your main application form's Load handler;这可能在您的应用程序的 main() 例程中,也可能在您的主应用程序表单的 Load 处理程序中; wherever you're creating large expensive objects, reading settings from the hard drive, and generally taking a long time to do stuff behind the scenes before the main application screen displays.无论您在何处创建昂贵的大型对象,从硬盘驱动器读取设置,以及在主应用程序屏幕显示之前通常需要很长时间在幕后做一些事情。

Then, all you have to do is create an instance of your form, Show() it, and keep a reference to it while you do your startup initialization.然后,您所要做的就是创建表单的一个实例 Show() 它,并在进行启动初始化时保留对它的引用。 Once your main form has loaded, Close() it.一旦你的主窗体加载完毕,关闭()它。

If your splash screen will have an animated image on it, the window will need to be "double-buffered" as well, and you will need to be absolutely sure that all initialization logic happens outside the GUI thread (meaning you cannot have your main loading logic in the mainform's Load handler; you'll have to create a BackgroundWorker or some other threaded routine.如果您的启动画面上有动画图像,则窗口也需要“双缓冲”,并且您需要绝对确定所有初始化逻辑都发生在 GUI 线程之外(这意味着您不能将主在主窗体的 Load 处理程序中加载逻辑;您必须创建一个 BackgroundWorker 或其他一些线程例程。

Here are some guideline steps...以下是一些指导步骤...

  1. Create a borderless form (this will be your splash screen)创建一个无边框表单(这将是您的启动画面)
  2. On application start, start a timer (with a few seconds interval)在应用程序启动时,启动一个计时器(间隔几秒钟)
  3. Show your Splash Form显示您的初始表单
  4. On Timer.Tick event, stop timer and close Splash form - then show your main application form在 Timer.Tick 事件中,停止计时器并关闭 Splash 表单 - 然后显示您的主应用程序表单

Give this a go and if you get stuck then come back and ask more specific questions relating to your problems试一试,如果您遇到困难,请回来询问与您的问题有关的更具体的问题

simple and easy solution to create splash screen创建启动画面的简单易用的解决方案

  1. open new form use name "SPLASH"打开新表单使用名称“SPLASH”
  2. change background image whatever you want随心所欲地更改背景图像
  3. select progress bar选择进度条
  4. select timer选择计时器

now set timer tick in timer:现在在计时器中设置计时器刻度:

private void timer1_Tick(object sender, EventArgs e)
{
    progressBar1.Increment(1);
    if (progressBar1.Value == 100) timer1.Stop();        
}

add new form use name "FORM-1"and use following command in FORM 1.添加新的表单使用名称“FORM-1”并在 FORM 1 中使用以下命令。

note: Splash form works before opening your form1注意:Splash 表单在打开表单 1 之前有效

  1. add this library添加这个库

    using System.Threading;
  2. create function创建函数

    public void splash() { Application.Run(new splash()); }
  3. use following command in initialization like below.在初始化中使用以下命令,如下所示。

     public partial class login : Form { public login() { Thread t = new Thread(new ThreadStart(splash)); t.Start(); Thread.Sleep(15625); InitializeComponent(); enter code here t.Abort(); } }

http://solutions.musanitech.com/c-create-splash-screen/ http://solutions.musanitech.com/c-create-splash-screen/

There is A Pretty Good Splash Screen over on CodeProject. CodeProject上有一个漂亮的启动画面

It comes with 它带有

  • Fade In 淡入
  • Progress Bar 进度条
  • Status Label 状态标签
  • Fade Out 淡出
  • Double Click to dismiss 双击关闭

The author has recently gone through and updated the code. 作者最近浏览并更新了代码。 It is really quite a piece of work, and is a collaboration between many different developers with good ideas. 这确实是一项艰巨的工作,并且是许多不同想法的开发人员之间的协作。

I wanted a splash screen that would display until the main program form was ready to be displayed, so timers etc were no use to me.我想要一个在主程序窗体准备好显示之前一直显示的启动画面,所以计时器等对我没有用。 I also wanted to keep it as simple as possible.我也想让它尽可能简单。 My application starts with (abbreviated):我的应用程序以(缩写)开头:

static void Main()
{
    Splash frmSplash = new Splash();
    frmSplash.Show();
    Application.Run(new ReportExplorer(frmSplash));
}

Then, ReportExplorer has the following:然后,ReportExplorer 有以下内容:

public ReportExplorer(Splash frmSplash)
{
    this.frmSplash = frmSplash;
    InitializeComponent();
}

Finally, after all the initialisation is complete:最后,在所有初始化完成后:

if (frmSplash != null) 
{
     frmSplash.Close();
     frmSplash = null;
}

Maybe I'm missing something, but this seems a lot easier than mucking about with threads and timers.也许我遗漏了一些东西,但这似乎比使用线程和计时器更容易。

create splash创造飞溅

private void timer1_Tick(object sender, EventArgs e)
{
    counter++;
    progressBar1.Value = counter *5;
    // label2.Text = (5*counter).ToString();
    if (counter ==20)
    {
        timer1.Stop();
        this.Close();
    }
}
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
this.ClientSize = new System.Drawing.Size(397, 283);
this.ControlBox = false;
this.Controls.Add(this.label2);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.label1);
this.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Splash";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.ResumeLayout(false);
this.PerformLayout();

Then in your application然后在您的应用程序中

sp = new Splash();
sp.ShowDialog();

The other answers here cover this well, but it is worth knowing that there is built in functionality for splash screens in Visual Studio: If you open the project properties for the windows form app and look at the Application tab, there is a "Splash screen:" option at the bottom.这里的其他答案很好地涵盖了这一点,但值得知道的是 Visual Studio 中的闪屏内置功能:如果您打开 windows 窗体应用程序的项目属性并查看应用程序选项卡,则会有一个“闪屏:" 选项在底部。 You simply pick which form in your app you want to display as the splash screen and it will take care of showing it when the app starts and hiding it once your main form is displayed.您只需在应用程序中选择要作为启动画面显示的表单,它会在应用程序启动时显示它,并在显示主表单后隐藏它。

You still need to set up your form as described above (with the correct borders, positioning, sizing etc.)您仍然需要按照上述方式设置表单(使用正确的边框、位置、大小等)

Maybe a bit late to answer but i would like to share my way.也许回答有点晚,但我想分享我的方式。 I found an easy way with threads in the main program for a winform application.我在主程序中为 winform 应用程序找到了一种使用线程的简单方法。

Lets say you have your form "splashscreen" with an animation, and your "main" which has all your application code.假设您有一个带有动画的表单“splashscreen”,以及包含所有应用程序代码的“main”。

 [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Thread mythread;
        mythread = new Thread(new ThreadStart(ThreadLoop));
        mythread.Start();
        Application.Run(new MainForm(mythread));           
    }

    public static void ThreadLoop()
    {
        Application.Run(new SplashScreenForm());           
    }

In your main form in the constructor:在构造函数的主窗体中:

 public MainForm(Thread splashscreenthread)
    {
        InitializeComponent();

        //add your constructor code

        splashscreenthread.Abort();            
    }

This way the splashscreen will last just the time for your main form to load.这样,启动画面将只持续主窗体加载的时间。

Your splashcreen form should have his own way to animate/display information.您的启动画面形式应该有自己的方式来制作动画/显示信息。 In my project my splashscreen start a new thread, and every x milliseconds it changes his main picture to another which is a slightly different gear, giving the illusion of a rotation.在我的项目中,我的启动画面开始一个新线程,每 x 毫秒它会将他的主图片更改为另一个略有不同的齿轮,给人一种旋转的错觉。

example of my splashscreen:我的启动画面示例:

int status = 0;
private bool IsRunning = false;
    public Form1()
    {
        InitializeComponent();
        StartAnimation();
    }

    public void StartAnimation()
    {
        backgroundWorker1.WorkerReportsProgress = false;
        backgroundWorker1.WorkerSupportsCancellation = true;
        IsRunning = true;
        backgroundWorker1.RunWorkerAsync();
    }


    public void StopAnimation()
    {
        backgroundWorker1.CancelAsync();
    }

    delegate void UpdatingThreadAnimation();
    public void UpdateAnimationFromThread()
    {

        try
        {
            if (label1.InvokeRequired == false)
            {
                UpdateAnimation();
            }
            else
            {
                UpdatingThreadAnimation d = new UpdatingThreadAnimation(UpdateAnimationFromThread);
                this.Invoke(d, new object[] { });
            }
        }
        catch(Exception e)
        {

        }
    }

 private void UpdateAnimation()
    {
    if(status ==0) 
    {
    // mypicture.image = image1
     }else if(status ==1)
     {
    // mypicture.image = image2
     }
    //doing as much as needed

      status++;
        if(status>1) //change here if you have more image, the idea is to set a cycle of images
        {
            status = 0;
        }
        this.Refresh();
    }

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        while (IsRunning == true)
        {
            System.Threading.Thread.Sleep(100);
            UpdateAnimationFromThread();
        }
    }

Hope this will help some people.希望这会帮助一些人。 Sorry if i have made some mistakes.对不起,如果我犯了一些错误。 English is not my first language.英语不是我的第一语言。

First you should create a form with or without Border (border-less is preferred for these things)首先,您应该创建一个带或不带边框的表单(这些东西首选无边框)

public class SplashForm : Form
{
    Form _Parent;
    BackgroundWorker worker;
    public SplashForm(Form parent)
    {
         InitializeComponent();
         BackgroundWorker worker = new BackgroundWorker();
         this.worker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.worker _DoWork);
         backgroundWorker1.RunWorkerAsync();
         _Parent = parent;
    }
    private void worker _DoWork(object sender, DoWorkEventArgs e)
    {
         Thread.sleep(500);
         this.hide();
         _Parent.show();
    }     
}

At Main you should use that在 Main 你应该使用它

   static class Program
        {
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new SplashForm());
            }
        }

I ended up doing slightly different, since I was not happy with the other solutions.我最终做的略有不同,因为我对其他解决方案不满意。 Basically I did not get them working as intended for some reason.基本上,由于某种原因,我没有让它们按预期工作。

I did not want the splash to show for a fixed period of time, but rather as long as the MainForm was loading, and load time vary depending on how fast the connection toward the DB was.我不希望飞溅显示一段固定的时间,而是只要 MainForm 正在加载,加载时间就会根据与数据库的连接速度而有所不同。

In short my MainForm constructor spawn a thread that show my SplashForm , and on the event OnShown the splash thread is aborted.简而言之,我的MainForm构造函数生成了一个显示我的SplashForm的线程,并且在OnShown事件中,启动线程被中止。 At first this did not work, and the SplashForm would at some times hang (hidden), and when closing the MainForm it would wait on the splash thread to exit.起初这不起作用, SplashForm有时会挂起(隐藏),当关闭 MainForm 时,它会等待启动线程退出。 The solution was to catch the ThreadAbortException and call Dispose on the form.解决方案是捕获ThreadAbortException并在表单上调用Dispose

Example code示例代码

private readonly Thread _splashThread = null;

public MainForm() {
    InitializeComponent();
    _splashThread = new Thread(new ThreadStart(DoSplash));
    _splashThread.Start();
}

private void DoSplash()
{
    var splashForm = new SplashForm();
    try
    {
        splashForm.ShowDialog();
    }
    catch (ThreadAbortException)
    {
        splashForm.Dispose();
    }
}

protected override void OnShown(EventArgs e)
{
    if (_splashThread != null && _splashThread.IsAlive)
    {
       _splashThread.Abort();
    }
    base.OnShown(e);
}

Here is the easiest way of creating a splash screen:这是创建启动画面的最简单方法:

First of all, add the following line of code before the namespace in Form1.cs code:首先,在Form1.cs代码中的命名空间前添加以下代码行:

using System.Threading;使用 System.Threading;

Now, follow the following steps:现在,请按照以下步骤操作:

  1. Add a new form in you application在您的应用程序中添加一个新表单

  2. Name this new form as FormSplashScreen将此新表单命名为 FormSplashScreen

  3. In the BackgroundImage property, choose an image from one of your folders在 BackgroundImage 属性中,从您的文件夹之一中选择一个图像

  4. Add a progressBar添加进度条

  5. In the Dock property, set it as Bottom在 Dock 属性中,将其设置为底部

  6. In MarksAnimationSpeed property, set as 50在 MarksAnimationSpeed 属性中,设置为 50

  7. In your main form, named as Form1.cs by default, create the following method:在默认名为 Form1.cs 的主窗体中,创建以下方法:

     private void StartSplashScreen() { Application.Run(new Forms.FormSplashScreen()); }
  8. In the constructor method of Form1.cs, add the following code:在Form1.cs的构造函数方法中,添加如下代码:

     public Form1() { Thread t = new Thread(new ThreadStart(StartSplashScreen)); t.Start(); Thread.Sleep(5000); InitializeComponent();//This code is automatically generated by Visual Studio t.Abort(); }
  9. Now, just run the application, it is going to work perfectly.现在,只需运行该应用程序,它就会完美运行。

None of the other answers gave me exactly what I was looking for.其他答案都没有给我确切的答案。 Read on for my solution to the problem.请继续阅读我对问题的解决方案。

I want a splash screen to fade in from 0% opacity to 100% opacity while things boot up, with a minimum display time of 2000ms (to allow the full fade in effect to show).我希望启动画面在启动时从 0% 不透明度淡入到 100% 不透明度,最小显示时间为 2000 毫秒(以显示完全淡入效果)。 Once everything is ready, I want the splash screen to display for a further 500ms while the main screen displays behind the splash screen.一切准备就绪后,我希望闪屏再显示 500 毫秒,而主屏幕显示在闪屏后面。 Then I want the splash screen to go away, leaving the main screen running.然后我希望闪屏消失,让主屏幕运行。

Note that I use the MVP pattern for winforms.请注意,我对 winform 使用了 MVP 模式。 If you don't use MVP, you will need to simplify the below example a little.如果您不使用 MVP,则需要稍微简化以下示例。

Long story short, you need to create an AppContext class that inherits from ApplicationContext .长话短说,您需要创建一个继承自ApplicationContextAppContext类。 I have put this in my Program.cs as below:我已经把它放在我的Program.cs ,如下所示:

static class Program
{
    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new AppContext());
    }
}

public class AppContext : ApplicationContext
{
    private IMainPresenter _mainPresenter;
    private bool _ready;

    public AppContext()
    {
        _ready = false;

        using (ISplashPresenter splashPresenter = new SplashPresenter(new SplashView()))
        {
            Stopwatch sw = Stopwatch.StartNew();

            _mainPresenter = new MainPresenter(new MainView());
            _mainPresenter.Closed += MainPresenter_Closed;

            new Thread(() =>
                {
                    // !!! Do work here !!!

                    if (sw.ElapsedMilliseconds < 2000)
                        Thread.Sleep(2000 - (int)sw.ElapsedMilliseconds);

                    _ready = true;
                })
                .Start();

            while (!_ready)
            {
                Application.DoEvents();
                Thread.Sleep(1);
            }

            _mainPresenter.Show();

            _ready = false;

            new Thread(() =>
                {
                    Thread.Sleep(500);

                    _ready = true;
                })
                .Start();

            while (!_ready)
            {
                Application.DoEvents();
                Thread.Sleep(1);
            }
        }
    }

    private void MainPresenter_Closed(object sender, EventArgs e)
    {
        ExitThread();
    }
}

There are several implementation specific details that I haven't gone into here, such as ISplashPresenter implementing IDisposable and exactly how the fade in is managed;有几个具体的实现细节我在这里没有ISplashPresenter ,例如ISplashPresenter实现IDisposable以及如何管理淡入; if enough people request it I will edit this answer to include a complete example.如果有足够多的人要求,我将编辑此答案以包含一个完整的示例。

Try this code试试这个代码

public partial class ssplashscreen : Form
    {
        public ssplashscreen()
        {                
            InitializeComponent();    
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            progressBar1.Increment(1);
            if (progressBar1.Value == 100)
            {
                timer1.Stop();
                this.Hide();
                Form frm = new login();
                frm.Show();
            }
        }
    }

Try This:试试这个:

namespace SplashScreen
{
    public partial class frmSplashScreen : Form
    {
        public frmSplashScreen()
        {
            InitializeComponent();
        }

        public int LeftTime { get; set; }

        private void frmSplashScreen_Load(object sender, EventArgs e)
        {
            LeftTime = 20;
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (LeftTime > 0)
            {
                LeftTime--;
            }
            else
            {
                timer1.Stop();
                new frmHomeScreen().Show();
                this.Hide();
            }
        }
    }
}

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

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