1

I was not able to find anything directly to fix this problem of mine. I am trying to make a animated gif as a loading screen for few places in my program where the loading time is quit long.

I got it working in the startup but once I try to use it once again it crashes my program. I have never fully understood the entire threading so something might have been wrong in my code.

[EDIT] What I want is to get the Loading screen to happend when a heavy methode is running lets say when its getting all the data from a database or just a simple Thread.Sleep(####) and in this moment I want a dynamic splashscreen to run where this screen is my secound window with a animated gif on it. I got the window and gif running.

The Windows I will be going over is

  • MainWindow.xaml
  • Loading.xaml
  • App.xaml

Loading.xaml

The only thing there is on this page is a animated gif using the WpfAnimatedGif package. and the rest of the window is transperant.

    public partial class Loading : Window, ISplashScreen
    {
    public Loading()
    {
        InitializeComponent();
    }

    public void LoadStart()
    {
        Dispatcher.Invoke((Action)delegate()
        {
            //this.UpdateMessageTextBox.Text = message;
        });
    }

    public void LoadComplete()
    {
        Dispatcher.InvokeShutdown();
    }
    }

    public interface ISplashScreen
    {
       void LoadStart();
       void LoadComplete();
    }
    }

App.xaml

    public partial class App : Application
        {
            public static ISplashScreen splashScreen;

            private ManualResetEvent ResetSplashCreated;
            private Thread SplashThread;
            protected override void OnStartup(StartupEventArgs e)
            {
                // ManualResetEvent acts as a block. It waits for a signal to be set.
                ResetSplashCreated = new ManualResetEvent(false);

                // Create a new thread for the splash screen to run on
                SplashThread = new Thread(ShowSplash);
                SplashThread.SetApartmentState(ApartmentState.STA);
                SplashThread.IsBackground = true;
                SplashThread.Name = "Splash Screen";
                SplashThread.Start();

                // Wait for the blocker to be signaled before continuing. This is essentially the same as: while(ResetSplashCreated.NotSet) {}
                ResetSplashCreated.WaitOne();
                base.OnStartup(e);
            }

            private void ShowSplash()
            {
                // Create the window
                Loading animatedSplashScreenWindow = new Loading();
                splashScreen = animatedSplashScreenWindow;

                // Show it
                animatedSplashScreenWindow.Show();

                // Now that the window is created, allow the rest of the startup to run
                ResetSplashCreated.Set();
                System.Windows.Threading.Dispatcher.Run();
            }
        }
    }

MainWindow.xaml

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Action that takes time here
            App.splashScreen.LoadComplete();
        }

    private void _btnVisUKategorier_Click(object sender, RoutedEventArgs e)
    {
        App.splashScreen.LoadStart();
        FyldUKategorier();
        App.splashScreen.LoadComplete();
    }

PS: If you know of any better solution that would do the same as I am trying to do here feel free to give out a link for it.

[Edit] I changed so I no longer use the app.xaml since I dont want it in my startup I moved the code into mainwindow where its going to be used.

It's not crashing anymore now but it only shows my window the first time, anything beyond this does simply not show anything.

[Edit-2] I ran some tests and decided to make the window look alot better and that's when I ran into where the exact problem is at. It seems like the code above works fine now after I moved it into my Main instead of making it run at the App.xaml. I removed the

    public void LoadStart()
    {
        Dispatcher.Invoke((Action)delegate()
        {
            //this.UpdateMessageTextBox.Text = message;
        });
    }

also from Loading.xaml since I dont have anything to use if for. The thing it was used for back in the exampel I was following was to update the label on the page itself.

The problem seems to be with the packages I installed that should have showed me the animated gif.

    <Image gif:ImageBehavior.RepeatBehavior="Forever" gif:ImageBehavior.AnimatedSource="/img/Animated_ARKA_Loading.gif" />

New Problem still same project

Okay so the next problem in this is when I show the loading screen it works the first time secound time it runs the window is empty.

The fix to getting the Loading over to the point I wanted it is in the solution below and the crash appeared because I tried to enter a thread that was closed. I thought I could start it with the methode so I eneded up removing it.

MainWindow

    private void AnimatedLoading()
    {
        // ManualResetEvent acts as a block. It waits for a signal to be set.
        ResetSplashCreated = new ManualResetEvent(false);

        // Create a new thread for the splash screen to run on
        SplashThread = new Thread(ShowSplash);
        SplashThread.SetApartmentState(ApartmentState.STA);
        SplashThread.IsBackground = true;
        SplashThread.Name = "Splash Screen";
        SplashThread.Start();

        // Wait for the blocker to be signaled before continuing. This is essentially the same as: while(ResetSplashCreated.NotSet) {}
        ResetSplashCreated.WaitOne();

        FyldUKategorier();

        splashScreen.LoadComplete();
        SplashThread.Abort();
    }

    private void ShowSplash()
    {
        // Create the window
        Loading loading = new Loading();
        splashScreen = loading;

        // Show it
        loading.Show();

        // Now that the window is created, allow the rest of the startup to run
        ResetSplashCreated.Set();
        System.Windows.Threading.Dispatcher.Run();
    }

Loading.xaml

    public Loading()
    {
        InitializeComponent();
    }

    public void LoadComplete()
    {
        Dispatcher.InvokeShutdown();
    }
    }

    public interface ISplashScreen
    {
       void LoadComplete();
    }
BlackStarHH
  • 75
  • 2
  • 11
  • just adding a splashscreen is not gonna fix it tho since I alrdy did that in the first place but some of the loadings in the program is taking way 2 long so beeing able to see a moving loading makes the user understand that its actually not stuck just a none animated picture where it says Loading also seems kinda frozen. I have the splashscreen as a backup alrdy since that is working as it should :) I was following this http://dontpaniclabs.com/blog/post/2013/11/14/dynamic-splash-screens-in-wpf/ to try to get this to work in the first place – BlackStarHH Oct 06 '16 at 09:58
  • hmm think you misunderstood what I was trying to get :) The blog works fine for one thing. thats for a startup loading where you dynamic can change the text on it. What I want is while the program is running and I click on a button and it then loads a shit ton from the database it will show the loading screen in the meantime. I am trying to do it away from the app.xaml right now but still havent found any fix for it. Where I am at atm is showing the loading the first time and secound time its empty – BlackStarHH Oct 06 '16 at 11:55
  • At the point of where `OnStartup()` returns do you have 2 windows open or just 1? In other words, is it your intent that you show a splash screen; close it after a bit; then open the `MainWindow`? –  Oct 06 '16 at 12:03
  • if I ran the onstartup it shows the screen fine and closes it after when the main shows up yes. and only one page is open at the time when that is happening. but like I said thats not what I want. – BlackStarHH Oct 06 '16 at 12:04
  • I donno I added a few Edit fields in the Thread here with updates on where I gotten to. It seems like I have to find another way of showing the Gif I might even go so far that with a loop and some Thread.Sleep(####) where its going to swap between 4 pictures to simulate the animation since the gif is only 4 pictures long anyways – BlackStarHH Oct 06 '16 at 12:33
  • https://i.gyazo.com/b55da8347aaf1af2986a558c09ec0ebb.gif This is how it should be https://i.gyazo.com/d924273ac52deaf3398da9fdd909de99.gif And this is how it ended up looking like after secound click – BlackStarHH Oct 06 '16 at 13:25

0 Answers0