I am trying to close a formular when opening a new one.
When closing an formular, I want to process some special logic in the closing event.
But the closing event is never called, neither in the FormClosing nor in the Closing event, nor in the abstract base class nor in the given manual attached event form_FormClosing
.
When I manual close the form by clicking the x all events are fired fine. Invoking the Close()
method fails.
Do you have some recmmendations to fix my issue?
MdiParent:
private Form _currentForm;
private void ShowForm<T>() where T : Form
{
if (_currentForm != null && !_currentForm.IsDisposed)
{
_currentForm.Hide();
_currentForm.Close();
}
var form = MdiChildren.FirstOrDefault(f => f.GetType() == typeof(T));
if (form == null)
{
form = _formFactory.CreateForm<T>();
form.MdiParent = this;
form.WindowState = FormWindowState.Maximized;
form.FormClosing += form_FormClosing;
_currentForm = form;
MdiBackground.Hide();
form.Show();
}
else
{
ActivateMdiChild(form);
form.Activate();
}
}
void form_FormClosing(object sender, FormClosingEventArgs e)
{
// will not be called
}
Abstract generic mdi child form:
public abstract partial class BaseForm<TEntity> : Form where TEntity : class, IEntity
{
protected override void OnClosing(CancelEventArgs e)
{
// wil not be called
if (EditMode == EditModes.Editable)
{
MessageBox.Show(this, "Please commit or abort your changes");
e.Cancel = true;
}
base.OnClosing(e);
}
}
This misbehaves because the native Windows MDI implementation doesn't support hiding MDI child windows. Winforms uses a trick to still support Hide(), it actually destroys the native window and re-creates it when you call Show() again. This has a side-effect however, the Close() call no longer raises the FormClosing/Closed events since the native window was already destroyed by the Hide() call. This is a bug, not uncommon in Winforms.
The workaround is simple, you don't need Hide() when you call Close(), just remove it.