SplashScreen.Close(Timespan.FromMilliseconds(int)):是否有在Timespan Complete发送的事件?
C#WPF应用程序SplashScreen.Close(Timespan.FromMilliseconds(int)):是否有在Timespan Complete发送的事件?
我有一个SplashScreen通过使用
Thread.Sleep(int); //int = milliseconds to display splash screen
当达到该睡眠时间被显示在启动时的最小时间量,代码恢复和闪屏淡出以关闭由使用
SplashScreen.Close(Timespan.FromMilliseconds(int)); //int = milliseconds fade-out
我想在这一点上暂停要等到闪屏已经成为100%透明和完全关闭,然后继续执行其它任务,IE写入控制台或显示MainWindow。
当(TimeSpan.FromMilliseconds(int))完成时是否触发事件? 还有其他建议吗?
namespace StartupSplash
{
public class SplashScreenStartup
{
//IMPORTANT:set image property to Resource and NOT Splash Screen
private SplashScreen Splash = new SplashScreen("Resources/SplashScreen.png");
public void SplashScreenStartUp()
{
Splash.Show(false, true);
Thread.Sleep(3000); // Pause code, display splash screen 3 seconds
Splash.Close(TimeSpan.FromMilliseconds(3000)); // 3 second splash fade-out
// I want to wait until splash screen fadeOut has completed before
// this next console output is performed.
Console.WriteLine("Executes before Splash fadeOut completes.");
}
}
我从来没有找到一个事件来听完TimeSpan的完成。另外,在决定不停止线程之后,我选择使用DispatcherTimers代替。
(我已经变薄,包含逻辑为供参考这一类)
using System;
using System.Windows;
using System.Windows.Threading;
namespace StartupSplash2
{
public partial class MainWindow : Window
{
private DispatcherTimer visibleTimer;
private DispatcherTimer fadeoutTimer;
private SplashScreen splash;
private int visibleTime = (4000); //milliseconds of splash visible time
private int fadeoutTime = (1500); //milliseconds of splash fadeout time
public MainWindow()
{
//hide this MainWindow window until splash completes
this.Visibility = Visibility.Hidden;
InitializeComponent();
splashIn(); //start the splash
}
private void splashIn()
{
splash = new SplashScreen("Resources/SplashScreen.png"); //ensure image property is set to Resource and not screen saver
visibleTimer = new DispatcherTimer(); //timer controlling how long splash is visible
visibleTimer.Interval = TimeSpan.FromMilliseconds(visibleTime);
visibleTimer.Tick += showTimer_Tick; //when timer time is reached, call 'showTimer_Tick" to begin fadeout
splash.Show(false, true); //display splash
visibleTimer.Start();
}
private void showTimer_Tick(object sender, EventArgs e)
{
visibleTimer.Stop();
visibleTimer = null; //clear the unused timer
fadeoutTimer = new DispatcherTimer();
fadeoutTimer.Interval = TimeSpan.FromMilliseconds(fadeoutTime); //a timer that runs while splash fades out and controlls when main window is displayed
fadeoutTimer.Tick += fadeTimer_Tick; //when fadeout timer is reached, call 'fadeTimer_Tick' to show main window
splash.Close(TimeSpan.FromMilliseconds(fadeoutTime)); //begin splash fadeout to close
fadeoutTimer.Start();
}
private void fadeTimer_Tick(object sender, EventArgs e)
{
fadeoutTimer.Stop();
fadeoutTimer = null; //clear the unused timer
splash = null; //clear the splash var
MainWindowReady(); //call method to display main window
}
public void MainWindowReady()
{
this.Visibility = Visibility.Visible;
//Here is the start of the Main Window Code
this.Content = "Ok, the app is ready to roll";
}
}
}
也许这段代码可以帮到你。使用BackgroundWorker类:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (o, ea) =>
{
// Dispatcher.Invoke commands the dispatcher to do something
Dispatcher.Invoke((Action)(() => Splash.Close(TimeSpan.FromMilliseconds(3000)));
// Sleeps this worker but NOT the UI
Thread.Sleep(3000);
};
worker.RunWorkerCompleted += (o, ea) =>
{
// Open your mainwindow sample
MainWindow w = new MainWindow();
w.Show();
};
//Runs the worker on its own thread
worker.RunWorkerAsync();
这应该启动溅射屏幕的关闭,然后通过它睡觉,当它这样做,它会打开你的主窗口。我实际上使用了与此类似的东西来为我的WPF应用程序实现登录和获取信息,同时显示进度条并更新其中的文本,如“连接到服务器”,“登录”和“获取数据”。
谢谢你的指导。起初我有一些错误,因为结束.DoWork和.RunWorkerCompleted的波形括号需要分号。但是,我仍然收到有关Dispatcher.Invoke的错误。在试图解决这个问题时,我发现下面的代码可以工作。 – reido113
哦,当然,对不起!你的错误:调度员在最后错过了一个括号。关于背景工作者:我发现你可以把你的代码放在里面,看看它是如何发展的。如果做某事给了threadlockedexception或什么的话,使用dispatcher.invoke动作。如果得到某些东西(比如int fadeOutTime)并且出现错误,请查看是否可以使用静态成员。这很简单,我真的很喜欢这个班。没有奇怪的东西与启动和锁定线程,这应该只做,如果你想要最佳性能,就像战地3或什么的。不是为了显示SS。 – AmazingDreams
我发现下面的代码有效。我不清楚为什么我会更深入地了解这一点。
请根据需要批评,我在这里学习和分享。干杯。
class Tester
{
// Create splash screen instance and reference the image location.
// IMPORTANT Ensure that the image properties are set to Resource and NOT Splash Screen
private SplashScreen Splash = new SplashScreen("Resources/SplashScreen.png");
public void Display()
{
Splash.Show(false, true);
// pause the code, thus, displaying the splash for 3 seconds
Thread.Sleep(3000);
// close the splash
Close();
}
private void Close()
{
// sets the fadeout time in milliseconds
int fadeOutTime = 1500;
// wait until the splash screen fadeOut has completed before writing to the console
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (o, ea) =>
{
// Run background task (fade out and close the splash)
Splash.Close(TimeSpan.FromMilliseconds(fadeOutTime));
// Sleep this worker but NOT the UI (for the same time as the fade out time)
Thread.Sleep(fadeOutTime);
};
worker.RunWorkerCompleted += (o, ea) =>
{
// Execute task after splash has closed completely
Console.WriteLine("This is after the splash screen fadeOut completes.");
};
// start the background task, on it's own thread
worker.RunWorkerAsync();
}
}
嗯......我的应用程序初始化需要很长时间才会显示一个启动画面,否则用户可能会认为他们没有正确地点击快捷方式,因此再次单击它,同时启动应用程序的两个实例(它两者的启动时间都是原来的两倍)......所以...我强烈建议您在启动屏幕显示时找到一种不睡觉主线程的方法,以便它可以启动您的应用程序。 。如果主窗体加载并显示启动画面(提示:allways-on-top),那么损伤是什么?干杯。基思。 – corlettk
非常好的点Keith。谢谢你的建议。当我更好地掌握BackgroundWorker和多线程时,我会改进这一点。队友的欢呼声。 Reid – reido113
我的基本想法是将所有事情都转移到了Doplash方法中的SplashScreen中,以便它在后台线程中显示,暂停和淡出所有内容......然后这只是您的主FormLoaded事件中的一个方法调用ShowSplashScreenInTheBackground处理程序...但我坚持让它显示在所有的方式......叹! – corlettk
我最终得出的结论是,我在之前的评论中咆哮了错误的树。在后台显示SplashScreen是有问题的(它拒绝自动关闭,不管我尝试了什么)和unessary。这就是我最终的结局......非常简单!
using System;
using System.Net;
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1() {
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
// show the splash screen
// nb: Resources/SplashScreenImage.png file Properties ~ Build Action='Resource'
var splashScreen = new SplashScreen("Resources/SplashScreenImage.png");
splashScreen.Show(false); // don't close automatically
// ... initialise my application ...
Initialise();
// close the splash screen.
splashScreen.Close(TimeSpan.FromMilliseconds(250D));
}
private void Initialise() {
// do my long-running application initialisation on the main thread.
// In reality you'd do this download asyncronously, but in this case
// it serves as a simple proxy for some "heavy" inititalisation work.
textBox1.Text = new WebClient().DownloadString("http://*.com/questions/13213625/splashscreen-closetimespan-frommilliseconds-listen-for-closed-event");
}
}
}
我希望帮助......虽然我并不相信它将;-)
干杯。基思。
PS:我想知道为什么飞溅拒绝关闭?我猜它在内部依赖于仅在WPF的事件派发线程(无论它被称为)上可用(即可订阅)的事件。
起初,我认为TimeSpan完成时会有一个事件发生。为了避免停止线程,我开始寻求定时器的使用。一旦我回到正轨,我将会得到一个解决方案代码。这引发了我的学习。 :) – reido113
我假设这是WPF? –
是的。谢谢你指出。 – reido113
为什么你不在线程中这样做,只等到线程结束后,应该得到你想要的结果,并且非常简单地实现。 –