I'm trying to use a window as splash screen. I have this:
{
InitializeComponent();
new splash().ShowDialog();
}
in my main window to start up with and it works but on the window that I'm using as splash when I press start it stays blank. This is the code I'm using for the splash window:
public partial class splash : Window
{
public splash()
{
InitializeComponent();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
System.Threading.Thread.Sleep(3000);
Close();
}
As it is it just loads the window blank and after 3secs it moves on to the main window.
I want the splash window to load with a label and an image.
Any ideas?
Thanks
So, as I already mentioned it in my comment, here is an excellent guide on how to implement a splash screen for WPF applications. Also Microsoft offers an easier way if your splash screen is only an image (see here).
But the main problem with your code is the Sleep(3000) call, as it blocks the UI thread. Use a Timer instead, which you can start in the window loaded event handler, and close the window in the Timer's Elapsed event handler.
Hope this helps.
(Sorry for almost duplicating my comment, but at the third edit I realized it actually should be an answer :))
Related
I began using C# and WPF a few months ago and now I thought I'd try to learn some new techniques like using threading. So I have an app that I want to run all the time (using an infinity while loop) but show the dialog (main window) every minute. So I am doing this by using Threading and here is how i am doing this:
public MainWindow()
{
InitializeComponent();
while (true)
{
callmyfunction()
system.Threading.Thread.Sleep(1000);
}
}
In my callmyfunction(), I am calling the dialog (which is the main WPF application) so it will show. Here's how i am doing it:
public void callmyfunction()
{
this.ShowDialog();
}
I have a regular button and when you click on it, it should hide the main window. So my button function is like this:
private void Button_Click2(object sender, RoutedEventArgs e)
{
this.Hide();
}
So what I am doing is, I am loading the main window normally and it has a button, when I click on that button, it should hide the main window and the window should sleep as per the milli-seconds I specified in thread.sleep and then it will wake up, then again the dialog will appearand it will show the button and so on and so forth. This loop is working fine with me, but the issue I am having is that after the first dialog appears and I click on the button to hide the main window, the second time the main window appears, the button would appear as a "pressed" button, not as a new button. I think it's because I "pressed" on it the first time the main window appeared. And it stays like that until I stop the program and run it again.
So my question is, any idea how I can "reset" the button control? Or do I need to reset the mouse click event? Any pointers on this would be helpful.
You should run the loop on a background thread. If you run it on the UI thread, the application won't be able to respond to user input.
The easiest and recommended way to run some code on a background thread is to start a new Task.
Also note that you cannot access the window from a background thread so you need to use the dispatcher to marshal the call back to the UI thread.
The following sample code should give you the idea.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Task.Factory.StartNew(() =>
{
while (true)
{
Dispatcher.Invoke(() => callmyfunction());
System.Threading.Thread.Sleep(5000);
}
}, TaskCreationOptions.LongRunning);
}
public void callmyfunction()
{
WindowState = WindowState.Normal;
}
private void Button_Click2(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
}
My WPF Application startup is slow (Cold startup), and I want to make the application main window appear as soon as the user double-click on the application’s icon.
I read this Blog and I want to add a Splash screen to avoid this delay. I added a splash screen to my application (PNG Image) But I have a questions :
How can I add the initialize code to improve startup, Or the splash screen will shown until the application loaded all the required components ?
It depends on where you load the resources that are so time consuming that the MainWindow gets delayed so much. If you are already creating those in the <App.Resouces /> block in XAML then it's tricky.
When they are created as resources for your view model in the <MainWindow.Resources /> then quite simply create a tool window or similar containing your splash screen and show it within the Application_Startup event like:
public partial class App : Application
{
// A Splash-Window to overlay until everything is ready.
public SplashWindow AppLauncher = new SplashWindow();
private void Application_Startup(object sender, StartupEventArgs e)
{
AppLauncher.lblText.Content = "Loading data...";
AppLauncher.Show();
}
}
And when all resources are loaded in the MainWindow then on the Loaded event hide/dispose the window again.
public partial class MainWindow : Window
{
private void Window_Loaded(object sender, RoutedEventArgs e)
{
(App.Current as App).AppLauncher.Close();
}
}
My C# application starts by opening a form. In the constructor for that form I "showDialog" an openfiledialog. After selecting a file to open, the openfile dialog closes, the file is loaded and the contents displayed in the main form but the main form is buried behind every other open window on my desktop.
I have to find it in the task bar and bring it to focus. I just started the application, I want the form to have focus.
I have written other applications that do not use the openfiledialog and when I start them the main form opens with focus as you would expect.
How do I make the main form get focus after the openfiledialog closes?
I have tried
this.focus(),
this.activate(),
this.bringtofront();
and this.TopMost = true;
None of them make any apparent difference at all.
I have research this problem extensively and this are the things everyone suggests and say work, but they don't work for me. Some have insinuated that I am violating all that is holy by trying to make my form topmost. However, I don't think very many people would like to open an application and have the main form for it show up behind everything else.
Any one have any other ideas about how to make sure my form is "in front", topmost, has focus?
When you do it this way, your application will have a brief moment where no window is available to receive the focus after the dialog closes. Windows is forced to find another window to give the focus to, that will be a window of another app. Your main window eventually appears, now behind that other's app window.
Display the dialog in an event handler of the Shown event instead. Or use the boilerplate File + Open command.
SOLUTION: this.Activate(); works but if called from the form Load event.
This will set the window on top:
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
private void Form1_Load(object sender, EventArgs e)
{
....
//after your code place the call to the function at the end.
SetForegroundWindow(this.Handle);
}
Althought as Mr. hans said and very well you are better off with another design.
If you can, move the ShowDialog out of the constructor, or try putting this in the constructor:
this.Shown += OnShown;
and move your ShowDialog to here:
private void OnShown(object sender, EventArgs eventArgs)
{
var result = new OpenFileDialog().ShowDialog();
}
I only want a simple Splash Screen Example.
Get the Code, Insert my picture, add 2 lines of code to load and finish.
But all I can google is so complex, that is too much. I only want a form with a picture that goes more and more transparent until it hides automaticly and my window is shown.
I tried the "prettygoodsplashscreen" from Codeproject, but don't work for me.
Lang is c#.net 2.0
Creating the splash screen can be as simple or complex as you make/want it to be.
private void Form1_Load(object sender, System.EventArgs e)
{
// Display the splash screen
var splashScreen = new SplashForm();
splashScreen.Show()
// On the splash screen now go and show loading messages
splashScreen.lblStatus.Text = "Loading Clients...";
splashScreen.lblStatus.Refresh();
// Do the specific loading here for the status set above
var clientList = _repository.LoadClients();
// Continue doing this above until you're done
// Close the splash screen
splashScreen.Close()
}
Obviously the Splash Screen itself is something that you'd have to decide how you want it to look...
In order for your splash screen to be areal splash screen, it shouldn't have other code than displaying about what it's doing (loading clients, for instance) or show the progress of application startup through a ProgressBar control.
Here are the steps:
Instantiate a BackgroundWorker for which you will launch the loading within the BackgroundWorker.DoWork() method;
Within your main Form_Load() event, call BackgroundWorker.RunWorkerAsync() method;
Still in your Form_Load() event, after your call to RunWorkerAsync(), instantiate and display your splash screen to your user SplashForm.ShowDialog()
Report progress from within your LoadClient() method, for instance, with the BackgroundWorker.ProgressChanged() event (you may also report what it is your BackgroundWorker is doing ("loading clients...");
In your RunWorkerCompleted() event, you may Splash.Close() your splash screen form.
I shall add some further details later on. Have to go now.
For my WPF application, I am storing several user settings like window position, window state, and whether or not to display a welcome dialog. The problem is that while everything is loading up, I see a lot of flashing and flickering as the windows are loaded in, and then more flickering when the window is maximized after reading in the settings.
I am already using the built-in WPF PNG splash screen functionality, but is there a way to completely hide the rendering of all windows until everything is fully loaded in?
Edit the Application.xaml, remove the StartUpUri, instead set the StartUp event handler.
In Application.xaml.cs, edit the startup event handler to display the splashscreen, load your resources, create everything, then create the main window and show it.
<Application
...
StartUp="OnStartUp"
/>
And:
private void OnStartUp(Object sender, StartupEventArgs e)
{
var settings = LoadSettingsFrom... // Call your implementation of load user settings
// Example only, in real app do this if's section on a different thread
if (settings.doShowSplashScreen)
{
var splashScreen = new SplashScreen();
splashScreen.Show();
}
// Load and create stuff (resources, databases, main classes, ...)
var mainWindow = new mainWindow();
mainWindow.ApplySettings(settings); // Call your implementation of apply settings
if (doShowSplashScreen)
{
// send close signal to splash screen's thread
}
mainWindow.Show(); // Show the main window
}
You can set the windows WindowState to Minimized, then handle the ContentRendered event and set the WindowState to Normal or Maximized.
There are functions , BeginInit and EndInit, if you change properties inside these functions like..
BeginInit();
...
... // Do your code Initialization here...
...
EndInit();
then your window will not render until the EndInit() is called, it will not flicker.
When does this loading occur? Code executed in the main Window's constructor should execute before the window is shown; if you load any required resources there, you should not see any flickering.