What causes WPF App to close - c#

I've ran into a weird bug where a WPF app is closing after the first window closes. This has made me curious what is triggering it to close
For example this is what I was the unworking version. After the EULAWindow would close it would shut down the application.
EULAWindow eula = new EULAWindow();
eula.ShowDialog();
MainMenuWindow mainWindow = new MainMenuWindow();
mainWindow.ShowDialog();
I thought it would open the EULA and then open the Menu window. I've found that if I rearranged the code it will operate like expected.
For example this will fix it:
EULAWindow eula = new EULAWindow();
MainMenuWindow mainWindow = new MainMenuWindow();
eula.ShowDialog();
mainWindow.ShowDialog();
This brings me to the question of what actually is causing the application to shut down in the first situation?

ShowDialog() is a blocking call. So, in the first case you have single window, then show it, then let user to close it. What should an app to do once last UI window is closed? Maybe, follow to app shutdown code? I suspect so.
In the 2nd case you create two windows before the blocking inside ShowDialog(). So, once you closed the first window, there is another one that could accommodate the user, and the app is not shutting down, it just waits for the next window to be shown.

Since I was using Application Startup to create my windows, it was defaulting setting the EULAWindow to the Current.MainWindow Then keeping the Current.ShutDownMode as ShutdownMode.OnMainWindowClose.
When you create two windows, before calling Show or ShowDialog, it changes the shutdown mode automatically to ShutdownMode.OnLastWindowClose
I'm not certain how or where this happening, but I can tell this is the behavior that is happening upon further investigation.

Related

Winforms ShowDialog(this) blocks the switching windows of other applications to the foreground

When I open any dialog in my Winforms application then Windows 10 behaves oddly in these ways:
ALT-TAB no longer displays the list of windows
I cannot switch to hidden applications using taskbar icons - if I select a taskbar icon of a window that is not currently visible (even if it is not hidden by the winforms app) the icon just flashes and then stays highlighted, but is not brought to the foreground. I can use other applications that are visible. As soon as I close the dialog form the other I can use the windows of other applications correctly
If I switch to the application window that is behind the winforms application by clicking on it, I cannot go back to the winforms app either by ALT-TAB or by clicking on the taskbar icon. I can get back to it by minimizing the other application
I'm opening the dialogs with
dialogFormName.ShowDialog(this);
TopMost is set false on all forms and is not set in the code.
I've read about 50 related articles and the only problems seem to be either TopMost is set or ShowDialog is not called with the parent form. I'm not a regular Winforms developer so I'm probably doing something stupid. This is driving me crazy, so I'd really appreciate any help!
Edit: The same issues occur with MessageBox.Show(this, "test"). The issue does not occur with a newly created app just with a single button calling MessageBox.Show(this, "test"). The problem application uses EntityFramework but no other packages and the problem existed before I added EF.
After trying different scenarios I eventually found the issue. In my case I was calling ShowDialog() after a user clicks an item on a ContextMenu. The blocking of ALT-TAB was caused by the following code that attached the ContextMenu to the ListView that the menu was contextually for:
lstList.ContextMenu = myContextMenu;
As soon as I removed that association, the ShowDialog no longer blocked ALT-TAB.
Form.ShowDialog() blocks the parent form until it's closed.
Use Show() to display the form separately without blocking its parent.

Prevent MessageBox from minimizing other windows

In my project I have a MessageBox that pops up from time to time.
When I'm playing a game and the MessageBox appears, the game is minimized and I'm back to the desktop.
This might depend from app to app, but this specific app/game minimizes when MessageBox appears.
How to avoid this behavior? Is there anything I can do to the MessageBox to make it lose focus/not activated ? I tried to look at the MessageBox methods but no luck.
It sounds like you want the message box to be able to display while the rest of your code is still running. Type of messagebox you are using is modal and needs to be closed until it allows you to interact with the other open window.
I suggest you start a new thread for the message box so that the thread can continue to run allowing you to be able to interact with the other windows.

Debug not stopping after form closing in Visual Studio

Visual Studio Debug does not stop when i close the form that i write in C#. How can i stop debug process when i close form. I added Application.Exit() method in the form closing event but it didn't work.
Thank you.
Try this from here
If (System.Windows.Forms.Application.MessageLoop)
{
// Use this since we are a WinForms app
System.Windows.Forms.Application.Exit()
}
Else
{
// Use this since we are a console app
System.Environment.Exit(1)
}
EDIT:
If there are running infinite threads then do
Thread myThread = new Thread(...);
myThread.IsBackground = true; //set your running thread to background
myThread.Start(...);
And you can see how to? from here
Well this will be four years too late, however, I thought I'd post this for anyone else who runs into this issue (like I just did), sorry in advance if this is pretty basic, I'm fairly new to C# so this threw me for a bit.
I had the same issue as OP where, in my FormClosing event, neither Application.Exit() or Environment.Exit(0) would end the debugger.
The thing I found was looking at the reference count above my FormClosing event, it was showing '0 references'. I had just copied and pasted the closing event from another forum so there was no event handler to actually handle the event I had created/copied.
One easy way to resolve this (besides not copy and pasting code) was to create the event handler:
First go to the 'Form1.cs [Design]' tab
Navigate to the 'Properties' box
Click on 'Events'
Find 'FormClosing' and double click that
If you had the same issue you should now be able to see that there is at least 1 reference to the event. Now when you close the form it should also stop the debugger.
I landed on this question because VS was not stopping when a debugged application was shut down.
One way to see what might be causing the ide to hang is to click on pause and on the 'Debug Location' toolbar view any threads that are still running. For me I noticed that there was still a RabbitMq context that was not disposed of. So this was the clue i needed.
After I made the code change, VS now stops it debugging session once the application exits.
I know this is not a solution that you might be expecting but finding out why applications are not exiting properly or still keeping background processes alive is a very tricky subject. The active threads drop down is the best place to look imho.
Another possibility is, that your process runs in an exception which isn´t handled correctly. I used to show exception messages in self-build dialogs, but forgot to show the created window in one case. So the program ran into the exception, created the window but just didn´t show any sign of it... so the process kept running even when I closed the application.

Small flickering when showing a modal dialog in .NET

I'm experiencing a annoying issue in my .NET Windows Forms application.
I have a MainForm (A) and a progress form (B) that is shown modal when I start a long operation.
When the operation finishes, and B is closed, it seems that the window that is behind my application (is occurs usually with Skype) is brought to front during few milliseconds and, then my application is activated normally.
Is only a small flickering, but annoying. Here I write some tips that could help to find the solution:
I called showDialog without IWin32Window, but I added it without success result.
I closed B using Close(), then I tried Hide() and then Close() but did not help.
The code that executes the ShowDialog() is invoked from the UI thread, so it don't seem to be a threading issue.
Any clue would be appreciated. Thanks in advance.
I was experiencing these same symptoms and it was driving me crazy.
I finally discovered the problem was that i was calling this.Dispose() instead of this.Close() to close the modal window I'm not sure why I called this.Dispose() in the first place.
After switching methods, the problem went away.
I realize that this thread is old and this is not the cause of your problem, i am just trying to help anyone else who made the same mistake that I did.
Check if you DON'T call Hide or Close. The only way to avoid flickering is DialogResult.
Upd:
this.DialogResult = DialogResult.Ok
Check handlers OnFormClosing and etc. They might containt wrong method call.
The little trick is to set Owner explicitly
_dialog.Owner = this;
_dialog.ShowDialog();
People who are editing the post - _dialog.ShowDialog(this) works a bit different.
Look at owner = ((Control) owner).TopLevelControlInternal; in decompiled code
Edited by someone:
Or...
_dialog.ShowDialog(this);
These calls are identical according to MSDN
Do not call Close for modal window (it will not be disposed and memory leak is guaranteed)
Set this.DialogResult = DialogResult.OK
Call Dispose() from the parent, NEVER from the form you are closing
Remember of disposing all of your components holding by the form IContainer in Dispose(bool) (VS Designer implementation of Dispose(bool) is usually not enough not to have memory leaks)
In my case I was also facing the same issue in my VB.Net winform application but a bit different scenario.
I was having a user control which opens up a dialog using showdialog() say dialog1 and on filling some data it hides dialog1 and opens up dialog2 using showdialog() again.
In the process of hiding dialog1 and showing dialog2 flickering occurs and it shows the window at background for a moment.
After trying so many solutions and workarounds none work for me. I found one workaround myself which might help others.
To hide dialog1 I was using Me.Hide(), The solution is to change the opacity of form instead of calling Hide() method.
'Me.Hide()
Me.Opacity = 0
After this workaround the application works fine without any flickering issue.
PS: The above code lines are in VB.Net but enough for a .Net winform application developer to get the idea for fixing this issue.
Okay,
it sounds like
In the main window a user starts a long operation
You display a progress modal window
Operation completes you close the progress window
Your main window doesn't display immediately. Instead something behind it shows through for a second or less.
Your main window completes it's redraw operation and is 100% visible.
This happens more often when you have applications such as Skype running.
If that's the case there are many different possible causes. For example, your video drivers might have a bug in them causing delays in off screen compositing under certain conditions.
The system itself might even be experiencing a blocking CPU operation at the moment. This is something that could be caused by the time it takes your code to close the dialog and go back to the main form. You might look to see if there is anything else you are doing between the time the progress closes and you return UI control back to the user.
The system might simply be memory constrained and your operation causes a huge swap to disk. When the operation completes, windows might be notified that it needs to pull previously swapped memory from disk and shove it back into RAM, causing a delay.
I'd run the app with Nothing else loaded but task manager or resource monitor and see what happens. If the problem no longer occurs, then look into adding more RAM to your machine and/or ignore it.
If it's still occuring, and your memory usage leaves nearly nothing left then, again, add RAM or ignore.
If it's still occuring but memory usage is low, investigate your code to see what you are doing between the closing of the dialog and release of control of the main window back to the user.
You could try double buffering your form with this example:
Tends to eliminate flicker on screen updates.

Close a WPF window separately

Goal:
Enable closing of the application's window(s) independently without affecting others. The application is created in WPF.
Problem:
Can't close the window(s)
In winform, it is enough to have the code winform.close() to close down the window but it doesn't work in WPF.
You can have this code to close a specfic window:
Application.Current.Windows[0].Close();
but how would it work if you have many windows and you want to close a specific window without affecting the others?
Use the Application class to get the windows through Application.Windows-property exactly as you described. If you are in the code-behind of the window, call this.Close();
Configuration for multiple Windows
Set the main window to the Application.MainWindow property and set the Application.ShutdownMode to a appropriate value if you also want to hold the app open, if the main window is closed (e.g App.Current.ShutdownMode=ShutdownMode.OnExplicitShutdown; ).
I have already observed, that some people have had problems with the ShutdownMode. A workaround for this is to open the first window invisible and from this window, you open the visible application windows. This prevents the application from closing if the first created window will be closed. However you should be able to resolve this problem also over the ShutdownMode-property.
In scenarios with multiple windows, you can use Shutdown to close the app without closing every window.
I hope this answer is what your question is about. Make a comment if not.
I am agree with HCL. You can use this.Close(); from code-behind of the window, this will close WPF window as like winform.close();.
Or you can use following code for get the specific window for close
Window win = Application.Current.Windows.OfType<Window>().SingleOrDefault(w => w.Name == "Window Name");
win.Close();
just use this code to close the most recent window
Application.Current.Windows[Application.Current.Windows.Count - 1].Close();

Categories