C# 如何在windows窗体应用程序中构建初始屏幕?
我需要在应用程序启动时显示启动屏幕几秒钟。有人知道如何实现这一点吗C# 如何在windows窗体应用程序中构建初始屏幕?,c#,winforms,splash-screen,C#,Winforms,Splash Screen,我需要在应用程序启动时显示启动屏幕几秒钟。有人知道如何实现这一点吗 非常感谢您的帮助。以下是一些指导步骤 创建一个无边界表单(这将是您的启动屏幕) 在应用程序启动时,启动计时器(间隔几秒钟) 展示你的飞溅形式 在计时器上。勾选事件,停止计时器并关闭启动窗体-然后显示您的主申请窗体 试一试,如果你被卡住了,然后回来问一些与你的问题有关的更具体的问题。首先,将你的启动屏幕创建为一个无边界的、不可移动的形式,上面有你的图像,设置为最初显示在屏幕中央,按你想要的方式着色。所有这些都可以在设计器中设置;具
非常感谢您的帮助。以下是一些指导步骤
试一试,如果你被卡住了,然后回来问一些与你的问题有关的更具体的问题。首先,将你的启动屏幕创建为一个无边界的、不可移动的形式,上面有你的图像,设置为最初显示在屏幕中央,按你想要的方式着色。所有这些都可以在设计器中设置;具体而言,您希望:
- 将窗体的ControlBox、MaximizeBox、MinimizeBox和ShowIcon属性设置为“False”
- 将StartPosition属性设置为“中心屏幕”
- 将FormBorderStyle属性设置为“无”
- 将窗体的MinimumSize和MaximumSize设置为与其初始大小相同
如果您的启动屏幕上有一个动画图像,那么窗口也需要“双缓冲”,并且您需要绝对确保所有初始化逻辑都发生在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窗体应用程序的项目属性并查看应用程序选项卡,则会出现“启动屏幕”:选项。您只需选择应用程序中要显示为初始屏幕的表单,它将在应用程序启动时显示该表单,并在主表单显示后隐藏该表单
您仍然需要如上所述设置表单(具有正确的边框、位置、大小等)创建启动屏幕的简单易行的解决方案
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
构造函数生成一个显示mySplashForm
的线程,在事件OnShown
时,SplashThread被中止。起初这不起作用,SplashForm
有时会挂起(隐藏),关闭主窗体时,它将等待启动线程退出。解决方案是捕获ThreadAbortException
并调用窗体上的Dispose
示例代码
以下是创建初始屏幕的最简单方法: 首先,在Form1.cs代码中的名称空间之前添加以下代码行: 使用系统线程 现在,按照以下步骤操作:
sp = new Splash();
sp.ShowDialog();
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();
}