following situation: I got a splashscreen which has to fade in over 2 seconds (from transparent to opaque). While the window nicely fades in, the program should wait until it is fully visible (the Storyboard finished) and then it should continue doing it's stuff. While the window is fading in, the user should already see the animations of the control (so blocking the UI thread is not an option, of course). And with animations I mean the loading circle which spins happily.
After I found a nice variant of how to fade in and out a window with WPF's storyboards, I tried to accomplish this by using the EventWaitHandle. As my intialization routine already runs asynchronous I was able to use it. This blocked the worker thread and stopped my application doing the initialization stuff before the Splashscreen was fully visible. But somehow this has been broken after a while and it doesn't seem to be the best solution.
Here's how I'm doing it, currently:
public async Task Appear(double time)
{
Core.IDE.GetGUICore().GetUIDispatcher().Invoke(() =>
{
this.Opacity = 0;
this.Show();
_fadeInStoryboard = new Storyboard();
_fadeInStoryboard.Completed += this.FadeInAnimation;
DoubleAnimation fadeInAnimation = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(time)));
Storyboard.SetTarget(fadeInAnimation, this);
Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath(OpacityProperty));
_fadeInStoryboard.Children.Add(fadeInAnimation);
});
_currentHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
Core.IDE.GetGUICore()
.GetUIDispatcher()
.InvokeAsync(this._fadeInStoryboard.Begin, DispatcherPriority.Render);
_currentHandle.WaitOne();
}
/// <summary>
/// Hides the SplashScreen with a fade-out animation.
/// </summary>
/// <param name="time">The fade-out time in seconds.</param>
public void Disappear(double time)
{
Core.IDE.GetGUICore().GetUIDispatcher().Invoke(() =>
{
_fadeOutStoryboard = new Storyboard();
_fadeOutStoryboard.Completed += this.FadeOutAnimation;
DoubleAnimation fadeOutAnimation = new DoubleAnimation(1.0, 0.0,
new Duration(TimeSpan.FromSeconds(time)));
Storyboard.SetTarget(fadeOutAnimation, this);
Storyboard.SetTargetProperty(fadeOutAnimation, new PropertyPath(OpacityProperty));
_fadeOutStoryboard.Children.Add(fadeOutAnimation);
});
Core.IDE.GetGUICore()
.GetUIDispatcher()
.BeginInvoke(new Action(_fadeOutStoryboard.Begin), DispatcherPriority.Render, null);
}
private void FadeInAnimation(object sender, EventArgs e)
{
_currentHandle.Set();
}
private void FadeOutAnimation(object sender, EventArgs e)
{
this.Hide();
}
Is this the right approach? Any better solutions? Any ideas why it is broken? By the way, with broken I mean that the application continues doing its initialization stuff whilst the window is fading in, which ends in an animation which runs until it's probably at 30% visibility and then fading out because the main window already showed up.
Thanks in advance