none
Asynchronous OOB Splash Screen Animation

    Question

  • 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

    Monday, September 19, 2011 11:24 AM

Answers

  • 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, September 21, 2011 4:43 AM

All replies

  • 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

    Monday, September 19, 2011 2:42 PM
  • 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
    Tuesday, September 20, 2011 3:36 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 3:07 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, September 21, 2011 4:43 AM
  • Do you have an example of your solution. I am running into the same problem I believe.

    Wednesday, November 09, 2011 8:54 AM