我需要在应用程序启动时显示闪屏界面几秒钟。有人知道如何实现吗?
非常感谢您的帮助。
我需要在应用程序启动时显示闪屏界面几秒钟。有人知道如何实现吗?
非常感谢您的帮助。
以下是一些指南步骤...
试试这个方法,如果遇到问题,请回来询问与您的问题相关的更具体的问题。
创建启动画面的简单易行解决方案
现在在计时器中设置计时器间隔:
private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(1);
if (progressBar1.Value == 100) timer1.Stop();
}
在表单1中使用名称为"FORM-1"的新表单,并使用以下命令。
注意:在打开表单1之前,闪屏表单将起作用。
add this library
using System.Threading;
create function
public void splash()
{
Application.Run(new splash());
}
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();
}
}
new splash()
是什么? - Alex S.我希望有一个启动画面,直到主程序界面准备好显示,所以计时器等工具对我来说没有用处。我也想尽可能简单地保持它。 我的应用程序启动方式为(缩写):
static void Main()
{
Splash frmSplash = new Splash();
frmSplash.Show();
Application.Run(new ReportExplorer(frmSplash));
}
接下来,ReportExplorer具有以下功能:
public ReportExplorer(Splash frmSplash)
{
this.frmSplash = frmSplash;
InitializeComponent();
}
if (frmSplash != null)
{
frmSplash.Close();
frmSplash = null;
}
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();
其他答案并没有完全满足我的需求。接下来请看我解决问题的方案。
我希望有一个启动画面,从0%不透明度到100%不透明度淡入,最少显示2000毫秒(以展示完整的淡入效果)。一旦所有内容都准备好了,我希望启动画面再显示500毫秒,同时主屏幕在启动画面后面显示。然后我希望启动画面消失,只留下主屏幕运行。
请注意,我在winforms中使用MVP模式。如果您不使用MVP,您需要简化以下示例。
长话短说,您需要创建一个继承自ApplicationContext
的AppContext
类。我将其放在我的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();
}
}
这里有一些具体的实现细节我没有详细说明,比如ISplashPresenter
实现了IDisposable
接口以及淡入效果的具体管理方式。如果有足够多的人请求,我会编辑这个回答并提供完整的示例。
首先,您应该创建一个带有或不带边框的表单(无边框更适合这些事情)。
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();
}
}
在主函数中,你应该使用它
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new SplashForm());
}
}
[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();
}
这样,启动画面只会持续到主窗体加载完成。
您的启动画面应该有自己的动画/显示信息的方式。 在我的项目中,启动画面会启动一个新线程,在每个x毫秒内更改主图片为另一个略微不同的齿轮,从而产生旋转的 illusio。
我的启动画面示例:
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();
}
}
希望这能帮到一些人。如果我犯了一些错误,抱歉,因为英语不是我的母语。
这是我对一个关于2011的问题给出的2023年观点。
强制创建主窗体Handle
,以便通过BeginInvoke
将创建启动画面的消息发布到主窗体的消息队列中。这允许主窗体的构造函数返回。通常情况下,句柄(本机hWnd
)直到显示才存在。因此,在它仍然隐藏的时候,需要将其强制执行。
覆盖SetVisibleCore()
,防止主窗口在启动画面完成处理之前变为可见状态。
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
Debug.Assert(!IsHandleCreated, "Expecting handle is not yet created.");
// Ordinarily we don't get the handle until
// window is shown. But we want it now.
_ = Handle;
Debug.Assert(IsHandleCreated, "Expecting handle exists.");
// Call BeginInvoke on the new handle so as not to block the CTor.
BeginInvoke(new Action(()=> execSplashFlow()));
}
protected override void SetVisibleCore(bool value) =>
base.SetVisibleCore(value && _initialized);
bool _initialized = false;
private void execSplashFlow()
{
using (var splash = new SplashForm())
{
splash.ShowDialog();
}
_initialized= true;
WindowState = FormWindowState.Maximized;
Show();
}
}
启动界面示例
异步初始化可以在Splash类本身中执行,或者可以触发事件引起主应用程序执行操作。无论哪种方式,当关闭它自身时,主窗体都会将_initialized
布尔值设置为true
,现在可以显示启动界面。
public partial class SplashForm : Form
{
public SplashForm()
{
InitializeComponent();
StartPosition = FormStartPosition.CenterScreen;
FormBorderStyle = FormBorderStyle.None;
}
protected async override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible)
{
labelProgress.Text = "Updating installation...";
progressBar.Value = 5;
await Task.Delay(1000);
progressBar.Value = 25;
// SIMULATED background task like making an API call or loading a
// database (long-running task that doesn't require the UI thread).
labelProgress.Text = "Loading avatars...";
await Task.Delay(1000);
labelProgress.Text = "Fetching game history...";
progressBar.Value = 50;
await Task.Delay(1000);
labelProgress.Text = "Initializing scenario...";
progressBar.Value = 75;
await Task.Delay(1000);
labelProgress.Text = "Success!";
progressBar.Value = 100;
await Task.Delay(1000);
DialogResult= DialogResult.OK;
}
}
}