Creating program in C#, FormClosing event executes twice - c#

As I said in the title I am creating a program. However, I am facing the problem of the FormClosing event executing twice. The message box appears and the buttons perform their purpose well, but when I click "Yes" or "No", it repeats itself. Thankfully the "Cancel" button doesn't have this problem.
private void Form1_FormClosing (object sender, FormClosingEventArgs e)
{
DialogResult dialog = MessageBox.Show("Do you want to save your progress?", "Media Cataloguer", MessageBoxButtons.YesNoCancel);
if (dialog == DialogResult.Yes)
{
SaveFileDialog savefile = new SaveFileDialog();
savefile.Filter = "Text files|*.txt";
savefile.Title = "Save As";
savefile.ShowDialog();
System.IO.FileStream fs = (System.IO.FileStream)savefile.OpenFile();
Application.Exit();
}
else if (dialog == DialogResult.No)
{
MessageBox.Show("Are you sure?", "Media Cataloguer", MessageBoxButtons.YesNo);
Application.Exit();
}
else if (dialog == DialogResult.Cancel)
{
e.Cancel = true;
}
}
Nothing else I have found had helped me very much. Like I said earlier, the message box appears twice. That is my only problem. Everything else for this void works fine.

Your problem is that you are calling Application.Exit(). As MSDN says,
The Exit method stops all running message loops on all threads and
closes all windows of the application
In other words, it will fire the form closing event again.
To get around this, use Environment.Exit(0) instead.

Your second MessageBox does not make sense and you do not have to exit the application.
The window should close if you do not set e.Cancel to true:
https://msdn.microsoft.com/en-us/library/system.windows.window.closing%28v=vs.110%29.aspx
private void Form1_FormClosing (object sender, FormClosingEventArgs e) {
DialogResult dialog = MessageBox.Show("Do you want to save your progress?", "Media Cataloguer", MessageBoxButtons.YesNoCancel);
if (dialog == DialogResult.Yes) {
SaveFileDialog savefile = new SaveFileDialog();
savefile.Filter = "Text files|*.txt";
savefile.Title = "Save As";
savefile.ShowDialog();
System.IO.FileStream fs = (System.IO.FileStream)savefile.OpenFile();
} else if (dialog == DialogResult.No) {
if(MessageBox.Show("Are you sure?", "Media Cataloguer", MessageBoxButtons.YesNo) == DialogResult.No){
e.Cancel = true;
}
} else if (dialog == DialogResult.Cancel) {
e.Cancel = true;
}
}
I would not quit the app in a window closing event.
It is not designed to perform that task.
You could use the project settings to define when the application quits.
Or if you need more control than that, you may want to handle it in the App.cs.
But I wouldn't do it in here.

You really shouldn't be throwing more than a single messagebox at the user... you might want to read this, this, and this. That said, I consider exiting with a prompt to save as one of the good spots for one, but not two.
You've already got the correct mechanism in place (they can answer Yes, No, or Cancel). Revise your question to be more clear to the user: "Would you like to save your work before exiting?" If they cancel, then cancel like you are using e.Cancel. Otherwise, just let the form close on it's own.
If they answer no, don't ask again. I can hear them now...
"I already told you, just EXIT!!!"

Related

I have to click multiple times before the dialog box closes, or performs the next action...How do I fix this?

Here is my C# code:
private void StudentReg_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dialog = MessageBox.Show("Do you really want to close this window?", "Exit", MessageBoxButtons.YesNo);
if (dialog == DialogResult.Yes)
{
Application.Exit();
}
else if (dialog == DialogResult.No)
{
e.Cancel = true;
}
}
Depending on how you setup your application like if this is your main form or you have multiple you may need to just remove the event to avoid duplicate calls to it.
Remove the event handler before calling application.exit and I think your issue will be solved.
This is psuedo-code.
private void StudentReg_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dialog = MessageBox.Show("Do you really want to close this window?", "Exit", MessageBoxButtons.YesNo);
if(dialog == DialogResult.Yes)
{
StudentReg.FormClosing -= StudentReg_FormClosing;
Application.Exit();
}
else if(dialog == DialogResult.No)
{
e.Cancel = true;
}
}
I doubt if you really want Application.Exit();: you prompt (bold is mine)
Do you really want to close this window
It is the window (Form), not the entire Aplication you want to close. If it's your case, you can just do nothing and let the form (window) close itself:
private void StudentReg_FormClosing(object sender, FormClosingEventArgs e)
{
// Cancel closing (i.e. do NOT close the form) if and only if user's chosen "No".
// Do nothing (i.e. do not cancel) in other cases (let the form be closed)
// So we assign true (cancel) if "No" has been pressed, false otherwise
e.Cancel = MessageBox.Show(
"Do you really want to close this window?",
"Exit",
MessageBoxButtons.YesNo) == DialogResult.No;
}

FormClosing event fires twice after using exit button

I have a button for exiting the form and this is the code
DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.No)
{
}
else
{
Application.Exit();
}
I tried using debugger mode, and after I click yes, it goes through Application.Exit() and then fires up the FormClosing event then running the same dialog.
I also tried deleting the code in FormClosing event so it only has Application.Exit() but using Alt+F4 or clicking the X button will exit the application automatically.
My question is how can I question the user if he wants to exit the program but not firing the dialog twice?
Thanks in advance, and I'm letting you all know I'm just a beginner and this is my biggest project so I want to make this great.
Here's an example. It only asks for confirmation if the close was initiated by the user - you probably don't want a MessageBox popping up when Windows is restarting.
private void form_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
Application.Exit();
}
}
else
{
// Cancel the close
e.Cancel = true;
}
}
There are two ways to achieve this.
By unsubscribe the even on button click
As suggested in stuartd's answer, checking reason of closing (but there is a problem in his answer so adding this approach too with fix, so it will help future people.)
I am assuming, As you need this confirmation in both cases, button click and 'x' button click, you have put the same code in both handler.
Approach one
In the handler of button click, while you are asking for user confirmation and if user is clicking 'yes'.
Before the line,
Application.Exit();
you should unsubscribe the Form closing event. By doing this, It must not raise form closing event while performing Application.Exit()
assuming your form is MainForm and event is MainForm_Closing, it would look like,
private void btnClose_Click(object sender, EventArgs e)
{
DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
this.FormClosing -= MainForm_FormClosing;
Application.Exit();
}
}
so it will not raise form closing event while performing Application.Exit() and thus your problem will be solved.
Approach Two
As stuartd has suggested (which is more cleaner way according to me. +1 for that), you can check for form closing reason in Form Closing event handler.
Note that there is a little problem (bug) in his sample code [which you have already accepted as an answer!!]. After clicking 'x' button or Alt+F4 by mistake; if user clicks on 'No' on the confirmation message, then too form is being closed because there is no handling for else condition. Proper solution should be like below.
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
Application.Exit();
else
e.Cancel = true; //stopping Form Close perocess.
}
}

C# Windows Form formclosing error

i am pretty newbie for coding. Here is i am having a problem:
private void pano_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dialog = MessageBox.Show("Uygulamadan çıkış yapmak istediğinizden emin misiniz?", "Çıkış", MessageBoxButtons.YesNo);
if (dialog == DialogResult.Yes)
{
Application.Exit();
}
else if (dialog == DialogResult.No)
{
e.Cancel = true;
}
My purpose with this code block to ask user "are sure to quit" but unfortunetly when i close the application, i got notification window for 3 times? Is there any idea why thats happening or any solution?
Thanks a lot.
Nuri.
Firstly, as Steve pointed out, remove the 'Yes' part - if not explicitly canceled, the event will close that form as a result of clicking.
Now, for the problem of yours. Seems like your alert is called twice. I was able to solve that easily by making a static bool close_alert_shown, and when the first alert is shown, set it to true so that the next alert won't pop up.
Final code looks like that:
if (close_alert_shown) return;
close_alert_shown = true;
DialogResult dialog = MessageBox.Show("Uygulamadan çıkış yapmak istediğinizden emin misiniz?", "Çıkış", MessageBoxButtons.YesNo);
if (dialog == DialogResult.No)
{
e.Cancel = true;
close_alert_shown = false;
}
And on the top of the form (before the public Form1() contructor line):
static bool close_alert_shown = false;
What i suspect is when application is exiting, it is again calling form closing since we have subscribed for that event. I assume, simple fix would be unsubscribe from the event before calling exit.
this.FormClosing-=Form1_FormClosing;
Application.Exit();

Message box with “Yes”, “No” choices in C#?

I want to make a MessageBox confirmation. Here is the message box:
DialogResult dialog = MessageBox.Show("Etes vous sûre de vouloir fermer le programme ?", "Exit",MessageBoxButtons.YesNo);
if (dialog == DialogResult.Yes)
{
Application.Exit();
}
else if (dialog == DialogResult.No)
{
e.Cancel = true;
}
The problem is, when I click the YES Button, the popup does not close automatically. It will be closed after I click 2 times again.
It should be closed from the first time.
It seems pretty easy but I'm not sure where is my mistake;
If it's in main form close method you can use it like this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Really close?", "Exit", MessageBoxButtons.YesNo) ==
System.Windows.Forms.DialogResult.No)
e.Cancel = true;
}
If user press "Yes" your form will be closed due to no close cancellation.
If it is not main form close doesn't mean application exit. In this case you can close parent form explicitly after ShowDialog call.
Below is code to prompt message (Yes/No):
DialogResult dialogResult = MessageBox.Show("Are you sure to delete Yes/No", "Delete", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
/// do something here
}
Call Application.DoEvents() before Application.Exit(). But it is better to close parent form with Close() instead of Application.Exit.
switch (MessageBox.Show("Etes vous sûre de vouloir fermer le programme ?", "Your_Application_Name", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
{
case DialogResult.Yes:
Application.Exit();
break;
case DialogResult.No:
//Action if No
break;
}

Application Close on DialogResult

I have a C# GUI application. When the user clicks on the red 'X' (for closing the app) I want to show a message and ask if he really wants to close it.
I found a solution:
DialogResult dialog = MessageBox.Show("Do you really want to close the program?", "SomeTitle", MessageBoxButtons.YesNo);
if (dialog == DialogResult.Yes)
{
Application.Exit();
}else if (dialog == DialogResult.No)
{
//don't do anything
}
When the user clicks 'yes', the application should terminate completely. (Is Application.Exit() correct for this purpose?)
When the user clicks 'no', the DialogResult/MessageBox should close, but the application should stay opened. However, it closes!!
How can I avoid this?
BTW: I use Visual Studio 2010 and Winforms.
Use the FormClosing event from the Form, and the FormClosingEventArgs to cancel the process.
example:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dialog = dialog = MessageBox.Show("Do you really want to close the program?", "SomeTitle", MessageBoxButtons.YesNo);
if (dialog == DialogResult.No)
{
e.Cancel = true;
}
}
Use the form's FormClosing event of your program window. You can then set e.Cancel to true if the user clicks no:
this.FormClosing += (s, e) => {
DialogResult dialog = dialog = MessageBox.Show("Really close?", "SomeTitle",
MessageBoxButtons.YesNo);
if (dialog == DialogResult.No)
{
e.Cancel = true;
}
};
I guess you are using FormClosed. Are you? Then it's too late.
Try this
this.FormClosing += new FormClosingEventHandler(delegate(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Do you really want to exit this application?", MessageBoxButtons:=MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
});
Refer to Mudu's answer.
Basically unless you specify additional parameters to MessageBox.Show() you cannot get any result other than DialogResult.Ok from a default MessageBox.
The code you posted (minus your little typo of dialog = dialog =) works exactly as expected to me.
Also: Application.Exit() IS the correct way of closing an application :)

Categories

Resources