WPF hide a window in Closing event prevents from application terminating - c#

A simple question again.
I am using a window in a WPF as a child window, where I would rather have the 'X' button hide the window instead of close. For that, I have:
private void Window_Closing(object sender, CancelEventArgs e) {
this.Hide();
e.Cancel = true;
}
The problem is that when the parent window is closed, this never closes and keeps the app alive.
Is there a clean way to deal with this? I thought of adding a Kill flag to all my user controls (windows):
public bool KillMe;
private void Window_Loaded(object sender, RoutedEventArgs e){
KillMe = false;
}
private void Window_Closing(object sender, CancelEventArgs e) {
this.Hide();
if (!KillMe) e.Cancel = true;
}
Then in MainWindow_Closing() I would have to set all window KillMe flags to true.
Any better way than creating additional flags and forgetting to set them before closing?

You could call Shutdown in the "parent's" closing handler... This will cause your Cancel to be ignored.
From Window.Closing:
If Shutdown is called, the Closing event for each window is raised. However, if Closing is canceled, cancellation is ignored.

I usualy have my own AppGeneral static class for such cases. When I'm realy exiting app I'm setting AppGeneral.IsClosing static bool to true. And then, when closing:
private void Window_Closing(object sender, CancelEventArgs e) {
if (!AppGeneral.IsClosing)
{
this.Hide();
e.Cancel = true;
}
}
Also, you can kill the your own process (that's ugly but working :) ) Process.GetCurrentProcess().Kill();

You should use
Application.Current.Shutdown();
inside your master window closing method.
This should override canceling of any subwindow!

Related

Close application after closing dialog window

Sorry for (maybe) easy question, but how can I shut down application, when I close dialog window ( which I called before running MainWindow) ?
As I mentioned above, before running MainWindow in my application I call a Dialog window. In App.xml I added this:
Startup="Application_Startup"
Then in App.xml.cs I wrote this:
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
StartWindow startWindow = new StartWindow();
startWindow.ShowDialog();
}
}
In my StartWindow there are only two exits - connect button, that worked fine, and classic closing button on title bar. I would like this button to shut down my application.
In my class StartWindow I wrote this:
private void Window_Closed(object sender, EventArgs e)
{
DialogResult = false;
}
But it still runs my MainWindow after closing my StartWindow. I even tried
private void Window_Closed(object sender, EventArgs e)
{
DialogResult = false;
Application.Current.Shutdown();
}
But still. Even if in above code I changed rows.
What I am doing wrong? I suspect, that is very easy to program what I want, but I don't know how. Yet. Can you help me, please?
ShowDialog() has a return value.
bool? dialogResult = startWindow.ShowDialog();
if (dialogResult == false)
{
...
}
You have to set DialogResult in your StartWindow before closing it, but you have already done that.

Best Way to Close a Win Form

I need to close a form on a button click event.Here in my example I am hiding the form.Think this is not a good way.When I do only Close() the form is disposed forever and need to rerun the programme to retrieve it.
private void buttonClose_Click(object sender, EventArgs e)
{
this.Close(); //closing frmCalender
}
private void frmCalender_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
this.Hide();
e.Cancel = true;
}
}
Give me the best way to close a C# Windows Form.
If you want to close a form, call .Close().
When I do only Close() the form is disposed forever and need to rerun the programme to retrieve it.
When you close the form, I assume you have no references to it. If so, you can create a new copy of your form via the constructor (var form = new MyForm();).
Otherwise, after closing the form, I believe you should be able to call .Show() on it again, as long as something still has a reference to your form.
I think, the best approach would be:
private void buttonClose_Click(object sender, EventArgs e)
{
this.Hide();
}

Track closing event of windows form with validation of button clicked in the form

I have a form which contains a close button (there are many control in the form, but I am concerning about the close event) and a save button.
If a form have value in certain text box (say TextBox1),
Then I want to validate that the save button is clicked before closing the form (whether close button or the 'X' button at top is pressed).
But if there is no value in that text box or the form is just initialized and user just want to close the form, it simply closes the form. How to perform this validation.
I would follow the pattern of 99% of windows applications: allow to close a window, but ask to save changes if there are any. Here is a simple implementation of that pattern:
private bool _hasChanges;
private void textBox1_TextChanged(object sender, EventArgs e)
{
this._hasChanges = true;
}
private void form_FormClosing(object sender, FormClosingEventArgs e)
{
if (this._hasChanges)
{
var dialogResult = MessageBox.Show("Save changes?", "Confirm", MessageBoxButtons.YesNoCancel);
switch (dialogResult)
{
case DialogResult.Yes:
this.Save();
break;
case DialogResult.No:
this._hasChanges = false;
break;
}
e.Cancel = this._hasChanges;
}
}
private void Save()
{
// Save
this._hasChanges = false;
}
private void buttonSave_Click(object sender, EventArgs e)
{
this.Save();
}
private void buttonOk_Click(object sender, EventArgs e)
{
this.Close();
}
private void buttonCancel_Click(object sender, EventArgs e)
{
this._hasChanges = false;
this.Close();
}
The pivotal part is the boolean _hasChanges. If there are many controls that can cause changes this can be real pain. An alternative could be to use databinding to a class that implements INotifyPropertyChanged and subscribe to its PropertyChanged event.
Tie into the Closing Event and use your EventHandler to validate that textbox. Keep in mind that Closing occurs at the time the form is closing and (if memory servers correctly) there is a property on the eventarg that will let you cancel closing of the form. This event is raised regardless of how the request is executed.

How to make Close button work as Minimize: C# Winforms

How can I make the (default) Close button (at top right corner) in my application, to work it as Minimize.
Actually I want to minimize the application on clicking the cross-symbol, but exit the application, when use clicks on my menu option Exit.
I wrote this code for minimizing the form on clicking close button:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (minimize_on_close == "Yes")
{
e.Cancel = true;
this.WindowState = FormWindowState.Minimized;
}
}
and wrote this code for exiting the application, on clicking exit from menu options.
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
Application.Exit();
}
But now, when I click on Exit menu option, then also the form is being minimized, and not exiting.
Can anyone please help?
Check to see whether FormClosingEventArgs.CloseReason is equal to CloseReason.UserClosing before deciding to minimize the window. Alternatively, compare for CloseReason.ApplicationExitCall.
From the documentation for CloseReason:
Members
...
UserClosing
The user is closing the form through the user interface (UI), for example by clicking the Close button on the form window, selecting Close from the window's control menu, or pressing ALT+F4.
...
ApplicationExitCall
The Exit method of the Application class was invoked.
Try this
EDIT
May use Resize Event to do it,
private void Form1_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
this.Hide();
}
Then using the FormClosing Event to cancel Close and minimize the Form as below
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.WindowState = FormWindowState.Minimized;
}
}

Can't close C# application

I'm developing a C# application and when the user clicks on the X, the application gets minimized inside a trayicon. Like so:
private void frmChat_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
}
The application is really simple (only one form). The problem is that I can't manage to properly close the application. When the user rights clicks on the tray icon and he chooses "exit" he should be able to close the application. The problem is that even if the tray icon gets unloaded and the form is closed, the application still shows in the Task Manager as an active application. I'm closing the application like this:
private void chiudiToolStripMenuItem_Click(object sender, EventArgs e)
{
trayIcon.Dispose();
this.Close();
Application.Exit();
}
What am I missing here?
I did something similar a while back.
You need to know what is causing the form to close. So when you click on the X, there is a specific reason passed to the FormClosing event. Like so:
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
// don't close just yet if we click on x
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.Hide();
}
}
Also, I have other code from the context menu Exit click:
private void tsmiExit_Click(object sender, EventArgs e)
{
// close the application forefully
TerminateApplication();
}
/// <summary>
/// Closes the Application.
/// </summary>
private void TerminateApplication()
{
// need to forcefully dispose of notification icon
this.notifyIcon1.Dispose();
// and exit the application
Application.Exit();
}
Edit:
Note: When you click on the X button, the close reason will be a CloseReason.UserClosing. When Application.Exit is called, the FormClosing is called again with a CloseReason.ApplicationExitCall.
End Edit:
Hope this helps
Andez
The e.Cancel = true line in frmChat_FormClosing is blocking the app from shutting down.
You can solve this easily enough by adding a boolean field to your form class, named TerminatingApp. Set this to true before calling this.Close(). Inside frmChat_FormClosing check for the value of TerminatingApp and only set e.Cancel = true if TerminatingApp is false.
Something like this:
private void frmChat_FormClosing(object sender, FormClosingEventArgs e)
{
if (!TerminatingApp)
{
e.Cancel = true;
Hide();
}
}
private void chiudiToolStripMenuItem_Click(object sender, EventArgs e)
{
TerminatingApp = true;
trayIcon.Dispose();
this.Close();
Application.Exit();
}
Ciao, how does it work if you replace Application.Exit with Application.ExitThread ?
I am actually afraid that with your code, when you call this.Close you are getting into the previous method above with the cancelling...
This is where the documentation on Application.Exit() comes in handy (my emphasis in bold):
The Exit method stops all running
message loops on all threads and
closes all windows of the application.
This method does not necessarily force the application to exit. The
Exit method is typically called from
within a message loop, and forces Run
to return. To exit a message loop for
the current thread only, call
ExitThread.
You could call Environment.Exit(0) where the parameter is the exit code.
When you are calling "this.Close" its going to call "frmChat_FormClosing" and in that you are setting "e.Cancel = true" which is creating the problem, use some variable to identify from where close event is being called and set e.Cancel accordingly.
I have tried Environment.Exit(0). It works in this case, and it worked fine for me.
Everyone else is over doing it.
Just do Close();

Categories

Resources