I've got another Window besides my MainWindow in my Application and I override the closing-method like this because I don't want the Window to be fully closed:
private void Window_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
this.Visibility = Visibility.Hidden;
}
then in the constructor:
public Inputwindow()
{
InitializeComponent();
this.Closing += Window_Closing;
}
But now if I want to close my MainWindow, it only hides the MainWindow.
Can't figure out, how to get it to work.
Every WPF application has a property called Application.ShutdownMode, which determines when the application actually ends. By default, it is set to OnLastWindowClose, which means that the application won't end until all windows are closed (even if the main window closes). It sounds like you want your application to end when the main window closes even if other windows are not closed, just hidden, which would correspond to the OnMainWindowClose mode. Here is the relevant MSDN documentation: https://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode(v=vs.110).aspx
To set the property in your xaml, open the App.xaml file and add the ShutdownMode property like this:
<Application x:Class="TestClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ShutdownMode="OnMainWindowClose">
</Application>
Related
I have WPF application where I have changed the default entry point.
<Application x:Class="FrazerClient.App" Startup="AppStartup">
public void AppStartup(object sender, StartupEventArgs e)
{
// Does some minor work before an application window opens.
}
The minor work calls this a couple of times:
App.Current.Dispatcher.Invoke((Action)delegate
{
// Custom dialog window is opened
});
The second time this is called, App.Current becomes null. I am almost positive is has to do with the custom dialog window closing, but not really sure how to prevent the closing of the dialog window from nulling out App.Current when the last window closes.
This also prevents App.Current.Shutdown() from working.
Set ShutDownMode to OnExplicitShutdown so that closing the window does not automatically shutdown the application.
You usually do that in the Xaml of the application object
<Application x:Class="FrazerClient.App"
Startup="AppStartup"
ShutdownMode="OnExplicitShutdown">
Resolved with this code:
Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
I ran into a weird case where Close event of the child window propagate to the parent window and causes it to close as well.
I made a minimum example as shown below
For TestWindow there is nothing but the default WPF window generated by VS
and in App.xaml.cs I override the OnStartup event and use it as a custom Main function
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
TestWindow t = new TestWindow();
t.ShowDialog();
}
Now if you click on the X button to close TestWindow, the application shuts down instead of showing the MainWindow. If you comment out t.ShowDialog then the MainWindow will show just fine. Next if you listen to the Closing event of MainWindow you will find that it will trigger after the TestWindow closes which doesn't seem right to me
It's not actually propagating, WPF runs your first dialog and upon closing notices that the process has no further windows present. WPF posts an application quit message for later processing. In the meantime your code has proceeded to display a further window which when processing the message pump encounters the quit message and so closes the window and terminates your app.
Debug log:
Information: 0 : App OnStartup
Information: 0 : new MainWindow
Information: 0 : MainWindow closing
Information: 0 : App exiting
To resolve, you need to remove the StartupUri and instead handle the Startup event.
Change:
<Application x:Class="WpfCloseProblem.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCloseProblem"
StartupUri="MainWindow.xaml"> ...
...to:
<Application x:Class="WpfCloseProblem.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCloseProblem"
Startup="Application_Startup">
Then discard the code on OnStartup and instead define a handler for Startup:
//protected override void OnStartup(StartupEventArgs e)
//{
// base.OnStartup(e);
//
// TestWindow t = new TestWindow();
// t.ShowDialog();
//}
private void Application_Startup(object sender, StartupEventArgs e)
{
var main = new MainWindow();
TestWindow t = new TestWindow();
t.ShowDialog();
main.Show();
}
Previously I was able to confirm that after the dialog closed, MainWindow was created; loaded and closed in quick succession.
The way App works here is it chooses the first started window as the main window. So in your case, the TestWindow will be chosen as the main window. The ShutdownMode in your code is somehow set to OnMainWindowClose. So after closing TestWindow, all child windows (including your MainWindow) have their Closing fired.
So the problem here is not propagating up, but propagating down the closing event.
You should not create any window before your main window actually being started first. Or if you want, you can set ShutdownMode to OnLastWindowClose.
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Application.Current.ShutdownMode = ShutdownMode.OnLastWindowClose;
TestWindow t = new TestWindow();
t.ShowDialog();
}
Or you can set the MainWindow explicitly in the constructor of your main window:
public MainWindow(){
InitializeComponent();
Application.Current.MainWindow = this;
}
However if using ShowDialog(), there is no way for you to set the MainWindow explicitly. Because right after closing the TestWindow (at that time it's still main window), the whole app will be shutdown.
Edit:
I don't find any reference about this but it can be checked and we can be sure about that, here is the debugging:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new TestWindow();//not even need to be shown
var wm = Application.Current.MainWindow;// points to the new TestWindow
//If there is not any Window init here, the MainWindow is just null
}
I have a WPF project were I am using multiple WPF windows.
My WPF Windows are:
MainWindow
Window1
Login
I have to case scenarios, in the first one everything works fine but in the second I get a null reference exception.
First Scenario:
App.xaml is configured so as startup window to be MainWindow.
When user clicks on Button on MainWindow he is forwarded in Window1 were I have the following code:
MainWindow obj=(MainWindow)Application.Current.MainWindow;
private void button1_Click(object sender, RoutedEventArgs e)
{
obj.checkBox1.IsChecked = false;
}
2.Second Scenario:
App.xaml is configured so as startup window to be Login Window.
Code in Login:
private void button1_Click(object sender, RoutedEventArgs e)
{
var window=new MainWindow();
window.Show();
this.Close();
}
In this scenario when I click on button in Window1 a null reference exception is thrown for obj.
What is the difference in the initialization of MainWindow in these 2 cases that causes the exception in the 2nd case and how can I overcome it?
Well, the first Window being opened when you start the application, will become the window you get back when calling Application.Current.MainWindow.
In your case, that is Login, but in Window1 you expect it to be MainWindow, which is wrong. Since Login has been closed, you get null back, and the app crashes.
To fix this you have to make MainWindow the MainWindow :-)
You can do that in Login like so:
var window = new MainWindow();
Application.Current.MainWindow = window;
window.Show();
this.Close();
The this.Close() on your Login window in scenario 2 will close the application as this is the window being pointed to in your app.xaml file as the startup window. See the MainWindow property
MainWindow is automatically set with a reference to the first Window object to be instantiated in the AppDomain.
In the first scenario you don't close the MainWindow so the application continues. In the second one you close the Login window so the application exits.
In the first scenario you don't show where the user is forwarded to window1. It would be helpful to see that code as well.
It appears that second windows are not closing. Here is what I am doing....
I have created a new WPF project.
I placed a button in the main window.
I put the following code in the button to launch a second window and hide the main.
private void button1_Click(object sender, RoutedEventArgs e)
{
var projectWindow = new NewProjectInfo();
this.Hide();
projectWindow.Show();
}
-The new window is a blank window with nothing on it.
-In the "close" event of the new window I put the code to show the main window again.
private void Window_Closed(object sender, EventArgs e)
{
var mainWindow = new MainWindow();
mainWindow.Show();
}
If I run the program and close the main window without opening the second window, the programs ends like I would like it to.
If I click the button on the main window, taking me to the second window, then close that window, taking me back to the main window, then close the main window the program does not end. (meaning I have to hit the stop button in visual studio to get it to end)
It's like visiting the second window leaves some kind of process running.
So, when I close the main window I can just run the:
Application.Current.Close();
But is that safe? Do I run the chance of leaving something hanging? Or is there a better way to close that second window so when I close the main the program will end?
These lines
var mainWindow = new MainWindow();
mainWindow.Show();
create a new MainWindow and show it. The original MainWindow is still hidden.
To resolve your problem, you need a reference to the original MainWindow instance.
Perhaps you could pass this reference when you build your secondary window
// Create a NewProjectInfo instance and pass this
var projectWindow = new NewProjectInfo(this);
this.Hide();
projectWindow.Show();
And in the constructor of the projectWindow, save the reference passed in a global var
var MainWindow _originalReference;
public NewProjectInfo(MainWindow original)
{
_originalReference = original;
}
now the window close event could use the referenced window
private void Window_Closed(object sender, EventArgs e)
{
_originalReference.Show();
}
Instead of creating a new Main window, can you simply call Application.Current.MainWindow.Show(); in your closed event handler?
My application uses ClickOnce technology for deployment. However I have problem when user starts using the application. The scenario for reproducing the problem is as follows:
User clicks on application's shortcut in order to run the application
ClickOnce's "Launching application" dialog box appears in order to check for updates
"Launching application" dialog box disappears
Splashscreen appears
Main window (login window) appears - however it's not active nor has a focus
Because main window is not active, user has to click on it before he/she can start typing username and password. How can I resolve this problem so the main window is active after it appears? I've tried the following code but it's not working:
protected override void OnInitialized(EventArgs e)
{
while (!this.IsFocused) { this.Focus(); WPFWaitForPriority.WaitForPriority(DispatcherPriority.Background); }
base.OnInitialized(e);
}
Most likely you're giving focus to the splash screen. So when it closes nothing has focus any longer. After closing the form call the Select Method on the control you want to have focus(the username textbox i'm guessing).
Select for Focus
try this code:
Pseudo code:
OnShown
this.focus
I mean.
Use diffrent event.
I have a WPF / ClickOnce application and don't have the same problem. I don't use the StartupUri of App.xaml, I manually show the login window instead as follows in App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
this.Exit += new ExitEventHandler(App_Exit);
base.OnStartup(e);
ShowLogin();
}
private MainWindow _mainWindow;
private void ShowLogin()
{
_mainWindow = new MainWindow(delegate()
{
//.......
});
_mainWindow.Closed += new EventHandler(_mainWindow_Closed);
this.MainWindow = _mainWindow;
this.MainWindow.Show();
}
As per my understanding you can programatically trigger click event once inside constructor .
How about LoginForm.Activate() after the splash screen is closed and the LoginForm is displayed?
Maybe try to get focus on TextBox on that form. Login name for example.
I think OnInitialized event may be too early. OnShown should be good.
Are you using Visual Studio? I know if you go to the form properties under the project tab, you can specify the start up object. Perhaps you can specify your main form and the splashscreen can load in front of it.
have you tried:
protected override void OnInitialized(EventArgs e)
{
while (this.CanFocus) { this.Focus(); WPFWaitForPriority.WaitForPriority(DispatcherPriority.Background); }
base.OnInitialized(e);
}