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();
}