I have a winforms application and I need a good way to handle the following..
Basically, I have the main application form, and within that, I have child forms.
The user can hit 'close' on the parent form.
But within the child form, some things might be happening. For instance, I may have edited some databound fields.
I currently catch the close within the child, and correctly save any changes.
However, now I want the option to cancel the close. So the child form would prompt the user, and they could actually cancel the application from closing.
I tried e.Cancel within the child form closing event, but this isn't working- I'm assuming because the parent is still closing... Is there a way to cancel the parent form's closing process from within the child...?
I suggest subscribing for FormClosing
event in main form and validating states for each child form and prevent form close (if required). Below code might help you and give fair idea of details.
private void Main_FormClosing( object sender, FormClosingEventArgs e )
{
foreach(var f in childforms)
{
if(!f.CanClose())
{
e.Cancel = true;
return;
}
}
e.Cancel = false;
}
Here's a very simple example for one single child form. If the user entered something in Form2's textbox he will be prompted when he tries to close form1.
public partial class Form1 : Form
{
Form2 form2;
public Form1()
{
form2 = new Form2();
form2.Show();
InitializeComponent();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (form2.AskBeforeClosing)
{
e.Cancel = MessageBox.Show("Are you sure?","",MessageBoxButtons.OKCancel)==System.Windows.Forms.DialogResult.Cancel;
}
}
}
public partial class Form2 : Form
{
public bool AskBeforeClosing
{
get {
return textBox1.Text != "";
}
}
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
If you need to work with a variable number of children form, you have to do the following:
- Define a base class form that exposes a bool virtual readonly property
AskBeforeClosing
- Derive all child forms from this base class and override the property by using the specific logic to prevent accidental closing
- Keep all children forms in a list within form1.
- Loop the list inside the FormClosing event handler in order to find if AT LEAST one form have AskBeforeClosing = true. If so, prompt the user