Asynchronous OOB Splash Screen Animation
-
Monday, September 19, 2011 11:24 AM
Hi all,
I am producing a Silverlight OOB application which requires a bulk loading operation on startup. I have produced a simple UserControl to be shown as a splash screen, with a rotating image playing in a stoyboard, started within the UserControl OnLoaded event. This splash screen has a minimum display time of 5 seconds.
I have placed the bulk loading code within the DoWork method of a new BackgroundWorker running asynchronously to the UI thread, but my splash screen animation never runs - the animation stays on the first frame and disappears when the load has completed, which rather defeats the point of the splash screen! I know the storyboard itself is fine, as the animation plays when there is relatively little work to be done, but the problem occurs when the work load is high.
Do I need to just accept that the storyboard will not truly execute asynchronously (given the large size of the loading task), or does anyone have a suggestion that may help?
Cheers,
'Firebird
All Replies
-
Monday, September 19, 2011 2:42 PM
May be you can show the SplashScreen before loading and close the splashscreen on the Loaded event.
If you can share the code cn able to fix it
-
Tuesday, September 20, 2011 3:36 AM
Thanks for the quick reply.
That's exactly what I am doing; I show the splash screen directly from Application_Startup, the set a flag on completion of the loading operation to allow the splash screen to close and reveal the main interface underneath. I believe the problem arises as the amount of processing required for the loading stage is quite high, but I cannot believe that Silverlight Isn't up to the challenge using BackgroundWorker or equivalent.
I am using a custom Splash Screen controller class with an initialise function called in application startup:
public static void Initialize<T>(UserControl splashcontrol, int width, int height, WindowState postWindowState, bool initializeOnLoad, double minSplashTime) { if (App.Current.RootVisual == null) { Width = width; Height = height; PostWindowState = postWindowState; SplashControl = splashcontrol; DateTime n = DateTime.Now; StartTime = n; MinSplashTime = n.AddMilliseconds(minSplashTime); IsChangeOnLoad = initializeOnLoad; if (App.Current.IsRunningOutOfBrowser) { App.Current.MainWindow.Width = Width; App.Current.MainWindow.Height = Height; } CoreScreenType = typeof(T); LayoutRoot = new Grid(); LayoutRoot.VerticalAlignment = VerticalAlignment.Stretch; LayoutRoot.HorizontalAlignment = HorizontalAlignment.Stretch; LayoutRoot.Children.Add(splashcontrol); App.Current.RootVisual = LayoutRoot; CreateCoreView(); } } private static void CreateCoreView() { DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(500); timer.Tick += delegate(object sender, EventArgs e) { ((DispatcherTimer)sender).Stop(); CoreView = (Control)Activator.CreateInstance(CoreScreenType); CoreView.Opacity = 0; CoreView.IsHitTestVisible = false; if (IsChangeOnLoad) { CoreView.Loaded += new RoutedEventHandler(CoreView_Loaded); } LayoutRoot.Children.Add(CoreView); }; timer.Start(); } private static void CoreView_Loaded(object sender, RoutedEventArgs e) { CloseSplash(); }
Within the constructor for my 'CoreView' I then create a background worker to run async an carry out a bulk XML load-parse task and set a flag on completion which tells my splash screen to close within 'CloseSplash()'
Anything obviously stupid in this methodology? Could it be because I have the code in the constructor of my core view, rather than in an OnLoaded event, and construction resources are being tied up?
Cheers for your help,
'Firebird -
Wednesday, September 21, 2011 3:07 AM
Hi,
I suggest you to refer to the link below:
http://blogs.cynergysystems.com/2011/02/25/creating-a-silverlight-out-of-browser-splash-screen/
And download the full source code for the example: SplashScreen.zip
First, create a Storyboard for your Splash.
<Grid x:Name="LayoutRoot" Background="White"> <Grid.Triggers> <EventTrigger> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="image" Storyboard.TargetProperty="Width" From="200" To="500" Duration="0:0:2"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Grid.Triggers> <Image Name="image" Source="/SplashScreen;component/splash.jpg"/> </Grid>
Then, delete the Thread.Sleep(10000) in LongLoadingStub.xaml.cs
Then, change the code
timer.Interval = TimeSpan.FromMilliseconds(500);
to
timer.Interval = TimeSpan.FromMilliseconds(2000);
Hope it can help you.
-
Wednesday, September 21, 2011 4:43 AM
Hi, and thanks for your reply.
My code is already based on that example, and the code I posted in my previous post was part of it.
I have now solved my problem; the thread that I set up to run my loading code was called within a DispatcherTimer, thus executing on the UI thread and stalling my splash screen animation. I got around the issue by passing a reference to the custom DataGrid that I wished to popuate with the loaded files, and using a couple of BackgroundWorkers.
Thanks again for your input though,
'Firebird
-
Wednesday, November 09, 2011 8:54 AM
Do you have an example of your solution. I am running into the same problem I believe.

