I need to create loading window. Some splash screen that appears while main window is initializing and loading.
But my loading window contain animations and so on. So, everything, and from ctor too I need to make through Dispatcher. And as a result - system wait while main window is loaded than show loading window for a moment and then show main window....
And there is no sense in loading window at all :)
So, how to make my loading window in right way?
Thanks a lot!
You might need to use Multi-threading. Here is msdn on threads
http://msdn.microsoft.com/en-us/library/798axes2.aspx
and a tutorial:
http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx
and another one specifically for this:
http://msdn.microsoft.com/en-us/library/aa446493.aspx
Related
Background:
I'm trying to add an animation to a splash screen window in my WPF project. (Not using the actual SplashScreen control. I use a window.)
My reason for implementing the splash screen is beacuse there's a slight delay when the application is opened, due to the loading of data. Obviously, the splash screen's purpose is to aid the user experience, so the user knows the application has been executed.
Here's the idea behind my current approach:
Instantiate the splashscreen window at the beginning of the
constructor.
InitializeComponent() is called.
Close the splashscreen window.
Unfortunately, the animation in the splash screen doesn't start until after the InitializeComponent() method of the the main parent window is called; this occurs basically when I'd WANT TO close the splashscreen window anyway. Hence the animation is useless and doesn't start until it's too late.
My question:
Why does it not animate until after InitializeComponent() is called?
My current theory for why this happens is that it's because the splash
screen is being opened on the main UI thread. Am I correct?
Are there any workarounds that don't involve hijacking control of
the program and spawning the splashscreen in a new thread? (I don't want a solution that hackish)
And yes, I did browse this site for quite awhile and was unable to find a viable solution.
Processing time on the UI thread blocks the animation. No real way around it.
The best approach is to NOT spend so much time loading and blocking on the UI thread. I suggest that you could delay the loading of the data bound to your UI elements until after the initial load. That way, the InitializeComponents() should not take so long.
Basically, all your bindings should return no data to the controls until AFTER you initialize. This data initialization would preferably happen on a separate thread, and then notification would occur after the data has been loaded.
This would allow your splash screen to animate and you will have much more joy.
There are a few approaches that I've taken to handle this in the past, though #HighCore is right in the comments as well about your current problem
Use the SplashScreen class in the VisualBasic assembly
Use the WPF Splash Screen class
Regardless, these solutions boil down to threading, since the UI pipeline needs to render and you can't inherently do these things on the UI thread without blocking, particularly if you want animation.
I have tried using this code sample:
private void DoShortRunningTask()
{
using (new StWaitCursor())
{
Thread.Sleep(5000); // 5 sec delay.
.. do some work ..
}
}
From: http://www.codeproject.com/KB/cpp/WaitCursor.aspx
But it did not do anything for me, since I did not have a main form. I do not need a main form. My C# project type is Windows Application, but the only GUI it shows if any is error or success messages dialogs. Is there a way for me to fake the existence of a WinForm (so that it exists but is not visible)? Would the mouse cursor have to be over it in order to show up?
I don't think it would be good practice just to change the cursor when it's not in your UI. You wouldn't want another program messing with the cursor in your UI. If you just want to show that your application is running, have you thought of using a tray app. These are relatively simple to create.
Here's an example I just googled:
http://alanbondo.wordpress.com/2008/06/22/creating-a-system-tray-app-with-c/
You can also show speech bubble messages as your run progresses etc, if you want to let the user know things are happening.
I do not need a main form
Yes, you do. Any UI interaction needs a form, sorry.
way for me to fake the existence of a WinForm (so that it exists but is not visible)?
How is that faking?
Make a form, make it invisible (transaprent - check all the properties on the form class and you will find it) and finished ;) Standard approach. Also tell it not to show up in the forms collection in the bottom of the screen and minimize it and you are finished. nothing fake here.
TomTom++
Are you just wanting to change the current cursor?
Try this
http://www.csharp-examples.net/hourglass-wait-cursor/
I have an app which consist of three windows.
Main Window
Settings Window
Find Window
A dll needs to be initialized. THis is little time consuming, so i have it done via the backgroundworker. The backgroundworker is a private member of Main Window.
I need to check the status of the backgroundworker in the find window too. I can pass a reference of main window to find window and check the backgroundworker status.But is this way i have to do it. Or should i have the backgroundwroker in a seperate class(A singleton maybe) and check the status of the backgroundworker through that??
Not much experience in C# GUI programming.
Thanks
If the entire purpose of the BackgroundWorker is to load a DLL without clogging up the UI message pump and to be able to be queried in odd spots, I would probably go with a singleton/static class.
You can then can design custom events that each window can attach to, to monitor the current state of the loading process.
That being said, it's dependant on how you've set up the relationship between the main window and the find window.
If the main window does all of the find window creation, then another option would be attach the background workers events to public methods on the find window.
I think both of these would would well, but i'm sure someone else with more knowledge will enlighten us both :)
When starting my app I at first have to read in some data, have to init some forms and so on.
For that time the user sees just grey getting-ready to show something forms.
This lasts for a few seconds...
I thought of a Splash Screen that loads the data in a seperate Thread and also shows how long it will take. Or just a status bar?
How would you do something like this?
I'm using C# .NET 3.5 + Winforms
See this CodeProject article: A Pretty Good Splash Screen in C#
It implements a splash screen that:
Runs on a separate thread
Fades in as it appears, and fade out as it disappears
Displays a running status message that is updated using a static method
Displays and update a predictive self-calibrating owner-drawn smooth-gradient progress bar
Displays the number of seconds remaining before load is complete
Here's an example of what it looks like - maybe yours will be prettier. 8-)
With WindowsForm, the easier is to use Backgroundworker.
You can disables controls during loading and display a progress bar on startus bar with label as "loading data...".
MSDN link : http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
If it only lasts a few seconds then displaying the wait
cursor should be fine. Perhaps it can be arranged that the
main window is shown as quickly as possible and the rest is
started after the first screen update (e.g. using a timer).
This will reduce the perceived start-up time.
In order to reduce the startup time you may also consider
postponing some of startup actions if they are not strictly
necessary. It can be done later in the background using a
timer or on-demand.
I recently wrote a similar splash screen using Tom Clements as a basis. Take a look at My Splash Screen to see if it fits your needs.
I have an application written in .NET. The previous version had no problems: you double-click on the icon or run it from a command line and when it starts up, it's the main window and has focus as you'd expect.
The latest version displays a splash screen before the main window and now the splash screen comes to the foreground ok but the main one does not always end up the main window. Sometimes it does, sometimes it doesn't. (When launched from the command line it invariably doesn't). When the main window does not come to the foreground and get focus, the taskbar icon shows as a steady orange.
I see lots of hits on the net about how MS added a facility to prevent applications stealing focus from others, centered around the ForegroundLockTimeout registry setting and related settings, but the behaviors described above for the different versions happen on the same machine.
I have tried called Activate in the main form when it finally gets created, and also SetForegroundWindow, all to no avail.
Any help is appreciated.
You should probably have the splash screen set focus to the main app window as it is going away.
As far as Window's knows your splash screen IS your app since it's the first toplevel window shown after the process is started. So that window gets the focus, but any OTHER window trying to grab focus on that same app startup (the icon click/run command) is believed to be a focus thief.
You can get around this by having the window that Window's believes has a right to have focus be the one to transfer focus to a new window.
So you splash should SetFocus on the main window BEFORE the splash is destroyed. If you destroy the focus window, then the focus is nowhere, which is probably what is happening currently in your app.
Sounds like your main window doesn't always get the focus back from the splash screen. Have you tried simply calling SetFocus in the main form's OnLoad handler?MSDN
I just corrected a similar problem. Just make sure your splash screen closes after your main form as shown (it will show in background of the splash if your splash is "always on top").