简体   繁体   English

C# WinForm - 加载屏幕

[英]C# WinForm - loading screen

I would like to ask how to make a loading screen (just a picture or something) that appears while the program is being loaded, and disappears when the program has finished loading.我想问一下如何制作一个加载画面(只是一张图片什么的),在程序加载时出现,程序加载完成后消失。

In fancier versions, I have seen the process bar (%) displayed.在更高级的版本中,我看到了显示的进程栏 (%)。 how can you have that, and how do you calculate the % to show on it?你怎么能拥有它,你如何计算显示在它上面的百分比?

I know there is a Form_Load() event, but I do not see a Form_Loaded() event, or the % as a property / attribute anywhere.我知道有一个 Form_Load() 事件,但我没有看到 Form_Loaded() 事件,或者在任何地方都没有看到 % 作为属性/属性。

all you need to create one form as splash screen and show it before you main start showing the landing page and close this splash once the landing page loaded.您只需要创建一个表单作为启动画面并在主要开始显示登录页面之前显示它,并在登录页面加载后关闭此启动画面。

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

namespace MyTools
{
    public class SplashForm : Form
    {
        //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;
            splashForm = new SplashScreen();
            Thread thread = new Thread(new ThreadStart(SplashForm.ShowForm));
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        static private void ShowForm()
        {
            if (splashForm != null) Application.Run(splashForm);
        }

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

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

and the main program function looks like this:主程序函数如下所示:

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

Don't forget to add a form load event to your main form:不要忘记向主表单添加表单加载事件:

private void MainForm_Load(object sender, EventArgs e)
{
    this.WindowState = FormWindowState.Minimized; 
    this.WindowState = FormWindowState.Normal;
    this.Focus(); this.Show();
}

It will bring the main form to the foreground after hiding the splash screen.隐藏启动画面后,它将主窗体带到前台。

I had problem with all other solutions I found, specially those that show splash in other thread than gui thread and specially on Citrix.我发现的所有其他解决方案都有问题,特别是那些在 gui 线程以外的其他线程中显示飞溅的解决方案,特别是在 Citrix 上。

Example:例子:

  • Splash never closes Splash 永不关闭
  • Splash show on wrong monitor飞溅显示在错误的显示器上
  • Splash show ok but mainform is showing behind all other windows Splash 显示正常,但 mainform 显示在所有其他窗口后面

I ended up with this and it seems to work well.我结束了这个,它似乎运作良好。

Splash form:飞溅形式:

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

    private void pictureBox1_Click(object sender, EventArgs e)
    {

    }
}

Splash form cont:飞溅形式续:

partial class Splash
{
    private System.ComponentModel.IContainer components = null;

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    private void InitializeComponent()
    {
        System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Splash));
        this.pictureBox1 = new System.Windows.Forms.PictureBox();
        ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
        this.SuspendLayout();
        // 
        // pictureBox1
        // 
        this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
        this.pictureBox1.Location = new System.Drawing.Point(0, 0);
        this.pictureBox1.Name = "pictureBox1";
        this.pictureBox1.Size = new System.Drawing.Size(512, 224);
        this.pictureBox1.TabIndex = 0;
        this.pictureBox1.TabStop = false;
        this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click);
        // 
        // Splash
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(512, 224);
        this.ControlBox = false;
        this.Controls.Add(this.pictureBox1);
        this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
        this.Name = "Splash";
        this.ShowIcon = false;
        this.ShowInTaskbar = false;
        this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
        this.Text = "Splash";
        ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.PictureBox pictureBox1;
}

Main:主要的:

[STAThread]
static void Main(string[] _args)
{
    ShowSplash();
    MainForm mainForm = new MainForm();
    Application.Run(mainForm);
}

private static void ShowSplash()
{
    Splash sp = new Splash();
    sp.Show();
    Application.DoEvents();

    System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
    t.Interval = 1000;
    t.Tick += new EventHandler((sender, ea) =>
    {
        sp.BeginInvoke(new Action(() =>
        {
            if (sp != null && Application.OpenForms.Count > 1)
            {
                sp.Close();
                sp.Dispose();
                sp = null;
                t.Stop();
                t.Dispose();
                t = null;
            }
        }));
    });
    t.Start();
}

If you're going to show the SplashForm more than once in your application, be sure to set the splashForm variable to null otherwise you'll get an error.如果您要在应用程序中多次显示 SplashForm,请确保将 splashForm 变量设置为 null,否则您将收到错误消息。

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

Here is a much simpler way of doing a loading screen when opening the application.这是打开应用程序时加载屏幕的一种更简单的方法。

async private void Form1_Shown(object sender, EventArgs e)
            {
                pictureBox1.Visible = true;
                await Task.Delay(2000);
                pictureBox1.Visible = false;
    
            }

You can also use this... (the name of the form is "Home.cs")你也可以用这个...(表单的名字是“Home.cs”)

await Task.Delay(10000);
this.Hide();          
Home h1 = new Home();
h1.ShowDialog();
        

And in the properties of the form: Windowstate: Normal; Controlbox: False; ImeMode: NoControl并且在窗体的属性中: Windowstate: Normal; Controlbox: False; ImeMode: NoControl Windowstate: Normal; Controlbox: False; ImeMode: NoControl

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

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