Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在windows窗体应用程序中构建初始屏幕?_C#_Winforms_Splash Screen - Fatal编程技术网

C# 如何在windows窗体应用程序中构建初始屏幕?

C# 如何在windows窗体应用程序中构建初始屏幕?,c#,winforms,splash-screen,C#,Winforms,Splash Screen,我需要在应用程序启动时显示启动屏幕几秒钟。有人知道如何实现这一点吗 非常感谢您的帮助。以下是一些指导步骤 创建一个无边界表单(这将是您的启动屏幕) 在应用程序启动时,启动计时器(间隔几秒钟) 展示你的飞溅形式 在计时器上。勾选事件,停止计时器并关闭启动窗体-然后显示您的主申请窗体 试一试,如果你被卡住了,然后回来问一些与你的问题有关的更具体的问题。首先,将你的启动屏幕创建为一个无边界的、不可移动的形式,上面有你的图像,设置为最初显示在屏幕中央,按你想要的方式着色。所有这些都可以在设计器中设置;具

我需要在应用程序启动时显示启动屏幕几秒钟。有人知道如何实现这一点吗


非常感谢您的帮助。

以下是一些指导步骤

  • 创建一个无边界表单(这将是您的启动屏幕)
  • 在应用程序启动时,启动计时器(间隔几秒钟)
  • 展示你的飞溅形式
  • 在计时器上。勾选事件,停止计时器并关闭启动窗体-然后显示您的主申请窗体

  • 试一试,如果你被卡住了,然后回来问一些与你的问题有关的更具体的问题。首先,将你的启动屏幕创建为一个无边界的、不可移动的形式,上面有你的图像,设置为最初显示在屏幕中央,按你想要的方式着色。所有这些都可以在设计器中设置;具体而言,您希望:

    • 将窗体的ControlBox、MaximizeBox、MinimizeBox和ShowIcon属性设置为“False”
    • 将StartPosition属性设置为“中心屏幕”
    • 将FormBorderStyle属性设置为“无”
    • 将窗体的MinimumSize和MaximumSize设置为与其初始大小相同
    然后,您需要决定在哪里显示它,在哪里取消它。这两个任务需要在程序的主启动逻辑的两侧进行。这可能在应用程序的main()例程中,也可能在主应用程序窗体的加载处理程序中;无论您在何处创建大型昂贵的对象,从硬盘读取设置,通常在主应用程序屏幕显示之前需要花费很长时间在后台进行操作

    然后,您所要做的就是创建表单的一个实例,Show()它,并在启动初始化时保留对它的引用。加载主窗体后,将其关闭()


    如果您的启动屏幕上有一个动画图像,那么窗口也需要“双缓冲”,并且您需要绝对确保所有初始化逻辑都发生在GUI线程之外(这意味着您不能将主加载逻辑放在mainform的加载处理程序中;您必须创建BackgroundWorker或其他线程例程。

    首先,您应该创建一个有边框或没有边框的表单(对于这些事情,无边框是首选)

    基本上你应该用这个

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

    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();
    
    然后在你的申请中

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

    这里的其他答案很好地涵盖了这一点,但值得一提的是,Visual Studio中有内置的启动屏幕功能:如果打开windows窗体应用程序的项目属性并查看应用程序选项卡,则会出现“启动屏幕”:选项。您只需选择应用程序中要显示为初始屏幕的表单,它将在应用程序启动时显示该表单,并在主表单显示后隐藏该表单


    您仍然需要如上所述设置表单(具有正确的边框、位置、大小等)

    创建启动屏幕的简单易行的解决方案

  • 打开新表单使用名称“SPLASH”
  • 改变背景图像,随你所愿
  • 选择进度条
  • 选择定时器
  • 现在在计时器中设置计时器刻度:

    private void timer1_Tick(object sender, EventArgs e)
    {
        progressBar1.Increment(1);
        if (progressBar1.Value == 100) timer1.Stop();        
    }
    
    添加新表单使用名称“form-1”,并在表单1中使用以下命令

    注意:Splash表单在打开表单1之前工作

  • 添加此库

    using System.Threading;
    
  • 创建函数

    public void splash()
    {     
        Application.Run(new splash());
    }
    
  • 在初始化中使用以下命令,如下所示

    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();
        }
    }
    
  • 试试这段代码

    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();
                }
            }
        }
    
    试试这个:

    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();
                }
            }
        }
    }
    

    我想要一个启动屏幕,直到主程序窗体准备好显示为止,所以计时器等对我来说没有用。我还想让它尽可能简单。 我的应用程序以(缩写)开头:

    然后,ReportExplorer具有以下功能:

    public ReportExplorer(Splash frmSplash)
    {
        this.frmSplash = frmSplash;
        InitializeComponent();
    }
    
    最后,在所有初始化完成后:

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

    也许我遗漏了什么,但这似乎比在线程和计时器上胡闹容易多了。

    回答可能有点晚,但我想分享我的方式。 我找到了一种在winform应用程序主程序中使用线程的简单方法

    假设您有一个带有动画的表单“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());           
        }
    
    在构造函数的主窗体中:

     public MainForm(Thread splashscreenthread)
        {
            InitializeComponent();
    
            //add your constructor code
    
            splashscreenthread.Abort();            
        }
    
    这样,splashscreen将刚好持续加载主窗体的时间

    SplashScreen表单应该有自己的方式来设置/显示信息的动画。 在我的项目中,我的splashscreen启动了一个新的线程,每x毫秒它就会将他的主图片更改为另一个稍微不同的齿轮,给人一种旋转的错觉

    我的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();
            }
        }
    
    希望这能帮助一些人。
    如果我犯了一些错误,请原谅。英语不是我的第一语言。

    我最终做了一些不同的事情,因为我对其他解决方案不满意。由于某种原因,基本上我没有让它们按预期工作

    我不希望splash在一段固定的时间内显示,而是只要MainForm正在加载,加载时间就会根据连接到DB的速度而变化

    简言之,my
    MainForm
    构造函数生成一个显示my
    SplashForm
    的线程,在事件
    OnShown
    时,SplashThread被中止。起初这不起作用,
    SplashForm
    有时会挂起(隐藏),关闭主窗体时,它将等待启动线程退出。解决方案是捕获
    ThreadAbortException
    并调用窗体上的
    Dispose

    示例代码
    以下是创建初始屏幕的最简单方法:

    首先,在Form1.cs代码中的名称空间之前添加以下代码行:

    使用系统线程

    现在,按照以下步骤操作:

  • 在应用程序中添加新表单

    sp = new Splash();
    sp.ShowDialog();
    
  • 将此新表单命名为FormSplashScreen

  • 在背景图片中
    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();
            }
        }
    
    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);
    }
    
     private void StartSplashScreen()
     {
         Application.Run(new Forms.FormSplashScreen());
     }
    
     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();
     }