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."); 
     } 

    } 
+1

我假设这是WPF? –

+0

是的。谢谢你指出。 – reido113

+2

为什么你不在线程中这样做,只等到线程结束后,应该得到你想要的结果,并且非常简单地实现。 –

我从来没有找到一个事件来听完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应用程序实现登录和获取信息,同时显示进度条并更新其中的文本,如“连接到服务器”,“登录”和“获取数据”。

+0

谢谢你的指导。起初我有一些错误,因为结束.DoWork和.RunWorkerCompleted的波形括号需要分号。但是,我仍然收到有关Dispatcher.Invoke的错误。在试图解决这个问题时,我发现下面的代码可以工作。 – reido113

+0

哦,当然,对不起!你的错误:调度员在最后错过了一个括号。关于背景工作者:我发现你可以把你的代码放在里面,看看它是如何发展的。如果做某事给了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(); 
    } 

} 
+2

嗯......我的应用程序初始化需要很长时间才会显示一个启动画面,否则用户可能会认为他们没有正确地点击快捷方式,因此再次单击它,同时启动应用程序的两个实例(它两者的启动时间都是原来的两倍)......所以...我强烈建议您在启动屏幕显示时找到一种不睡觉主线程的方法,以便它可以启动您的应用程序。 。如果主窗体加载并显示启动画面(提示:allways-on-top),那么损伤是什么?干杯。基思。 – corlettk

+0

非常好的点Keith。谢谢你的建议。当我更好地掌握BackgroundWorker和多线程时,我会改进这一点。队友的欢呼声。 Reid – reido113

+0

我的基本想法是将所有事情都转移到了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的事件派发线程(无论它被称为)上可用(即可订阅)的事件。

+0

起初,我认为TimeSpan完成时会有一个事件发生。为了避免停止线程,我开始寻求定时器的使用。一旦我回到正轨,我将会得到一个解决方案代码。这引发了我的学习。 :) – reido113

我发现叫SplashScreen.Dismissed的事件,可以让你的闪屏到期后启动应用程序。但是,最低要求的操作系统是Windows 8,我无法使用它。 更多信息可在这里找到MSDN