Брызговик.Закрыть (Timespan.FromMilliseconds (int)): есть ли событие, отправленное в Timespan Complete?
на C# WPF-приложений
у меня есть SplashScreen отображается при запуске в течение минимального количества времени с помощью
Thread.Sleep(int); //int = milliseconds to display splash screen
когда это время сна достигнуто, код возобновляется, и SplashScreen исчезает, чтобы закрыть с помощью
SplashScreen.Close(Timespan.FromMilliseconds(int)); //int = milliseconds fade-out
Я хотел бы сделать паузу на этом этапе, чтобы дождаться, пока SplashScreen станет 100% прозрачным и полностью закрыт, а затем продолжить с другими задачами, т. е. Файл 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.");
}
}
5 ответов
возможно, этот код может вам помочь. Использование класса 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();
Это должно начать закрытие вашего splashscreen, затем проспать его, и когда это будет сделано, он откроет ваше главное окно. Я на самом деле использую что-то очень похожее на это, чтобы реализовать логин и получить информацию для моего приложения WPF, отображая индикатор выполнения и обновляя текст в нем до таких вещей, как "подключение к серверу", "вход в систему" и "извлечение данных".
Я обнаружил, что следующий код работает. Я не совсем понимаю, почему, и я буду углубляться ближе, чтобы лучше понять это.
прошу критики по мере необходимости, я здесь, чтобы учиться и делиться. Овации.
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();
}
}
в конце концов я пришел к выводу, что в моих предыдущих комментариях я лаял не на то дерево. Отображение SplashScreen в фоновом режиме является проблематичным (он отказался закрываться автоматически, независимо от того, что я пытался) и ненужным. Вот с чем я закончил... Очень просто!
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://stackoverflow.com/questions/13213625/splashscreen-closetimespan-frommilliseconds-listen-for-closed-event");
}
}
}
надеюсь, это поможет... хотя я совсем не уверен, что это будет; -)
Ура. Кит.
PS: интересно, почему всплеск отказался закрываться? Мое предположение это внутренне полагается на события, которые доступны только (т. е. подписываются) на эквиваленте WPF потока event-dispatch (независимо от того, как он называется).
Я никогда не находил событие для прослушивания по завершении 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";
}
}
}
Я нашел событие под названием SplashScreen.Уволен, что позволяет запустить приложение после истечения срока действия SplashScreen. Однако минимальная требуемая ОС-Windows 8, и я не мог ее использовать. Более подробную информацию можно найти здесь MSDN