Closing() with CancelEventArgs versus Form_Closing with FormClosingEventArgs - c#

We are currently upgrading and remodularizing our code as we transfer from 32 to 64 bit system. In due process, one of our goals is to change from an Init() function where things were added as such example.
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form_Closing);
I'd like Windows events to handle these sorts of things. So I went to the Form_Closing event in the Windows Form Events and [without surprise] saw that this was not the form_closing event. My question to this is, is there any difference between what is actually going on with CancelEventArgs vs FormClosingArgs, or are these two pieces of code literally doing the same thing with one being a Component of System and one being the result of a Windows Event handling what it does best? I'm just sort of diving and indulging myself into this new project as an intern. Is it possible to just replace the CancelEventArgs with the FormClosing one without any loss of data or issues?
Code 1: CancelArgs
private void Form_Closing(object sender, CancelEventArgs e)
{
// If the user hit Cancel, just close the form.
if (this.DialogResult == DialogResult.Ignore)
return;
if (this.DialogResult == DialogResult.OK)
{
// If the address is not dirty, just cancel out of
// the form.
if (!this._editedObject.IsDirty)
{
this.DialogResult = DialogResult.Cancel;
return;
}
// Save changes. If save fails, don't close the form.
try
{
SaveChanges();
return;
}
catch (Exception ex)
{
ShowException se = new ShowException();
se.ShowDialog(ex, _errorObject);
_errorObject = null;
e.Cancel = true;
return;
}
}
Form_Closing -- Preferred Route
private void ScheduleItemDetail_FormClosing(object sender, FormClosingEventArgs e)
{
// If the user hit Cancel, just close the form.
if (this.DialogResult == DialogResult.Ignore)
return;
if (this.DialogResult == DialogResult.OK)
{
// If the address is not dirty, just cancel out of
// the form.
if (!this._editedObject.IsDirty)
{
this.DialogResult = DialogResult.Cancel;
return;
}
// Save changes. If save fails, don't close the form.
try
{
SaveChanges();
return;
}
catch (Exception ex)
{
ShowException se = new ShowException();
se.ShowDialog(ex, _errorObject);
_errorObject = null;
e.Cancel = true;
return;
}
}
}

You don't get the CloseReason property with the CancelEventArgs class, which is the only difference, since FormClosingEventArgs inherits from the CancelEventArgs class. The FormClosingEventArgs was introduced in .Net 2.0.
Alternatively, instead of using the event, you could just override the OnFormClosing method, too.
protected override void OnFormClosing(FormClosingEventArgs e) {
// your code
base.OnFormClosing(e);
}

Related

Visual C# completely ignoring FormClosing event

My application appears to be skipping the Form_Closing event entirely, and I am not sure why. I have tried to debug it by using e.cancel and showing a messagebox when it closes, but the messagebox never shows, and the e.cancel doesnt cancel it. My code is
public void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (isClosed == false)
{
e.Cancel = true;
base.OnFormClosing(e);
this.Hide();
this.WindowState = FormWindowState.Minimized;
}
else
{
Application.Exit();
}
}
Thanks :)
Your method has the signature appropriate for a FormClosing event handler, but you are calling base.OnFormClosing which is only appropriate for an OnFormClosing override.
Pick one. For example, the override would look like
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (isClosed == false)
{
e.Cancel = true;
base.OnFormClosing(e);
Hide();
WindowState = FormWindowState.Minimized;
}
else
{
Application.Exit();
}
}
Start by only using a message box to determine that you hace the right event
Then check the value of isclosed since I suspect it is true.

Closing Form C#

Recently I had to edit my program code so that the form will close after creating a PDF. In FormClosing() there's a MessageBox.Show for closing or not, depending on the DialogResult. The problem is that when I try to Close(), it shows me the MessageBox, I need to close it without showing it. Thanks.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Exit?", "Exit", MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
private void btn_PdfCreate_CloseForm_Click(object sender, EventArgs e)
{
showPDf();
// close pdf but skip MessageBox
}
You can stop listening to the event like so
private void btn_PdfCreate_CloseForm_Click(object sender, EventArgs e)
{
this.FormClosing -= Form1_FormClosing
showPDf();
Close();
}
You can use the CloseReason property of the FormClosingEventArgs:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.ClosingReason == CloseReason.UserClosing && MessageBox.Show("Exit?", "Exit", MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
Use e.ClosingReason to find out if the formClosing event was fired by the user's attempt to close the form, or by something else.
for further reading, go to MSDN:
http://msdn.microsoft.com/en-us/library/system.windows.forms.formclosingeventargs.closereason(v=vs.110).aspx
You anyways want to close the form after pdf creation. So call Form's Dispose method just after pdf creation like below and no need of registering for the OnFormClosing event
private void btn_PdfCreate_CloseForm_Click(object sender, EventArgs e)
{
showPDf();
this.Dispose();
}

How to handle form closing events

I am using Windows Forms in c# and have problems with how and when the the different forms (i have 2) should close and not. It is very annoying since i feel that i should be able to fix it. But here we go.
I have two forms, one MainForm that calls another form called ContactForm.
The MainForm:
private void btnAdd_Click(object sender, EventArgs e)
{
ContactForm frmContact = new ContactForm();
int index = lstCustomers.SelectedIndex;
//If a customer is selected, export data for the selected customer to ContactForm
if (index != -1)
{
frmContact.ContactData = customerMngr.GetCustomer(index).ContactData;
}
if (frmContact.ShowDialog() == DialogResult.OK) //Show the ContactForm object
{
//The user has chosen the OK button - add the new customer object
customerMngr.AddCustomer(frmContact.ContactData); //??
UpdateCustomerList();
}
if (frmContact.ShowDialog() == DialogResult.Cancel)
{
return;
}
}
And the form that is called:
OK button.
private void btnOK_Click(object sender, EventArgs e)
{
if (ValidateInput())
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
Cancel button:
private void btnCancel_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Do you want to cancel and discard all data?", "Cancel input", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
When the OK button in the ContactForm is used i want it to close, which works. When i press the cancel button, and no (in the box that appears), i want the form to stay open with the input still intact. Right now it doesn´t work.
Any ideas?
/Martin
Your code is alright. I think the problem lies in your Cancel Button itself. By this I mean that you probably attached (by designer or somewhere in code) DialogResul.Cancel to your button btnCancel.DialogResul property. To fix this simply set it to DialogResult.None.
If I'm right this is what is closing your second form.
See MSDN for more information.

Observe which window sent a Close() event

I have a short questions and even after a while of searching through the web I have not found the answer.
I have two windows in a WPF application. One window should just be hidden when the user closes it. When the main window is closed the complete application shall close.
I used
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
Hide();
}
inside the class of the second window and hoped it would just catch its Close() event but unfortunately it catches all Close() events.
How can I separate between the windows to handle the events independently?
Regards
Larimow
Use the sender parameter, that's what it's there for:
window1.Closing += Window_Closing;
window2.Closing += Window_Closing;
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
var w = (Window)sender;
// Simple ref test to illustrate, but you can use anything else you want instead
if (w == window1) {
e.Cancel = true;
w.Hide();
}
}

Windows form application can't be closed normally

I have problem when closing the windows form application. I need to know is it always called private void Form1_FormClosing(object sender, FormClosingEventArgs e) if I press X button on the form and if I just click to shut down computer?
Anyone neither of this times form is not closed as normally. I always have screen to press End now
I have connecting to the databases when form is closing, and copying some records to another database. Is that maybe the problem? Form is closing to fast and sql commands can't finish?
I have tried Enviroment.Exit(0), Application.Exit(). Nothing seems to be working correctly.
How to make it do all the sql and then quit?
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//close database connection
if (Con.State == ConnectionState.Open)
Con.Close();
info.Dispose();
//last check for local database
try
{
// database queries and so on....
}
catch (Exception ex)
{
writeToLogFile(ex.Message);
}
// exit
Environment.Exit(0);
}
UPDATE (based on your last comment):
private const int WM_QUERYENDSESSION = 0x11;
private const int WM_CANCELMODE = 0x1f;
private bool shutdownRequested = false;
...
protected override void WndProc(ref Message ex)
{
if (ex.Msg == WM_QUERYENDSESSION)
{
Message MyMsg = new Message();
MyMsg.Msg = WM_CANCELMODE;
base.WndProc(ref MyMsg);
this.shutdownRequested = true;
}
else
{
base.WndProc(ex);
}
}
...
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.Visible = false; // optional
this.ShowInTaskbar = false; // optional
Task db = Task.Factory.StartNew(() => DBUpdate();
Task.WaitAll(db); // you can have more tasks like the one above
if (this.shutdownRequested)
Process.Start("shutdown.exe","-s");
}
private void DBUpdate()
{
// write your db code here
}
I believe that this will work.
Anyone neither of this times form is not closed as normally. I always have screen to press End now
Are you saying you want the application to automatically shutdown if the computer is restarted or shut down?
If so, just hook up an event to the Microsoft.Win32.SystemEvents.SessionEnding event.
Microsoft.Win32.SystemEvents.SessionEnding += new Microsoft.Win32.SessionEndingEventHandler(SystemEvents_SessionEnding);
void SystemEvents_SessionEnding(object sender, Microsoft.Win32.SessionEndingEventArgs e)
{
// Run your application shut down code here...
}

Categories