This should be an easy google search but I can't find the answer. When I click the close button on my form I want to check and warn the user if information on the form has changed. For this my code is adequate. But if the user clicks the X button on the top of the form no check is performed. So I tried using the "FormClosing" event to execute the same code below but it goes into some weird loop, I think because i have used this.close which also triggers the same FormClosing event.
What is the correct way to check for form changes when either a button or the X is clicked.
private void buttonClose_Click(object sender, EventArgs e)
{
// Close the form and warn if record not saved
//Check for unsaved changes
if (formDataChanged == true)
{
DialogResult dr = new DialogResult();
dr = MessageBox.Show("Data on this form has changed, Click OK to discard changes", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
if (dr == DialogResult.OK)
{
this.Close();
}
}
else
{
this.Close();
}
}
Update I think the linked example may be too simple? When I looked at the CloseReason I received the same results when I closed the window either way so I'm not sure how I can use this to trigger different results.
CloseReason = UserClosing
Cancel = False
private void FormTelephoneLog_FormClosing(object sender, FormClosingEventArgs e)
{
System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
messageBoxCS.AppendFormat("{0} = {1}", "CloseReason", e.CloseReason);
messageBoxCS.AppendLine();
messageBoxCS.AppendFormat("{0} = {1}", "Cancel", e.Cancel);
messageBoxCS.AppendLine();
MessageBox.Show(messageBoxCS.ToString(), "FormClosing Event");
}
I tried adding a bool variable as was also suggested in the other post but it still loops. I know why because the this.close() command also triggers FormClosing event but I still can't figure out how I should do this correctly.
I see there are 6 possible scenarios.
- No changes, Close Button -> Works
- No changes, X Button -> Loops
- Discard changes, Close Button -> Works
- Discard changes, X Button -> Loops
- Don't Discard changes, Close Button -> Works
- Don't Discard changes, X button -> Fails ***
*** The form is still closed and the changes are discarded.
Here is the code as it is now. I'm going round and round including more and more conditions. This would seem like a very common thing to want to do. I'm missing something obvious.
private void buttonClose_Click(object sender, EventArgs e)
{
CloseButtonClicked = true;
checkFormChanges();
CloseButtonClicked = false;
}
private void FormTelephoneLog_FormClosing(object sender, FormClosingEventArgs e)
{
if (CloseButtonClicked == false)
{
checkFormChanges();
}
}
private void checkFormChanges()
{
// Close the form and warn if record not saved
//Check for unsaved changes
if (formDataChanged == true)
{
DialogResult dr = new DialogResult();
dr = MessageBox.Show("Data on this form has changed, Click OK to discard changes", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
if (dr == DialogResult.OK)
{
formDataChanged = false;
this.Close();
}
}
else
{
this.Close();
}
}
Update 2
I just kept adding conditions until all the possibilities worked. I think it is a confusing solution but it works.
Working Code
private void buttonClose_Click(object sender, EventArgs e)
{
closeButtonClicked = true;
checkSaveChanges();
closeButtonClicked = false;
}
private void FormTelephoneLog_FormClosing(object sender, FormClosingEventArgs e)
{
if (closeButtonClicked == false)
{
if (formDataChanged == true)
{
checkSaveChanges();
}
e.Cancel = closeCancelled;
closeCancelled = false;
}
}
private void checkSaveChanges()
{
// Close the form and warn if record not saved
//Check for unsaved changes
if (formDataChanged == true)
{
DialogResult dr = new DialogResult();
dr = MessageBox.Show("Data on this form has changed, Click OK to discard changes", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
if (dr == DialogResult.OK)
{
formDataChanged = false;
this.Close();
}
else
{
closeCancelled = true;
}
}
else
{
this.Close();
}
}