Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 未为MDI子窗体调用FormClosing事件_C#_Winforms_Mdi_Mdichild - Fatal编程技术网

C# 未为MDI子窗体调用FormClosing事件

C# 未为MDI子窗体调用FormClosing事件,c#,winforms,mdi,mdichild,C#,Winforms,Mdi,Mdichild,我试图在打开一个新公式时关闭一个公式。 当关闭一个公式时,我想在关闭事件中处理一些特殊的逻辑。 但是,无论是在FormClosing中,还是在closing事件中,抽象基类中,还是在给定的手动附加事件form\u FormClosing中,都不会调用closing事件 当我通过单击x手动关闭表单时,所有事件都会正常触发。调用Close()方法失败 你有一些建议来解决我的问题吗 MdiParent: private Form _currentForm; private void ShowForm&

我试图在打开一个新公式时关闭一个公式。 当关闭一个公式时,我想在关闭事件中处理一些特殊的逻辑。 但是,无论是在FormClosing中,还是在closing事件中,抽象基类中,还是在给定的手动附加事件
form\u FormClosing
中,都不会调用closing事件

当我通过单击x手动关闭表单时,所有事件都会正常触发。调用
Close()
方法失败

你有一些建议来解决我的问题吗

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
}
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);
    }
 }
private Form\u currentForm;
私有void ShowForm(),其中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();
form.MdiParent=此;
form.WindowState=FormWindowState.Maximized;
form.FormClosing+=form_FormClosing;
_当前形式=形式;
mdiback.Hide();
form.Show();
}
其他的
{
活化二碘甲烷(形式);
form.Activate();
}
}
作废表单\表单关闭(对象发送方,表单关闭目标)
{
//不会被叫
}
抽象通用mdi子表单:

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
}
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);
    }
 }
公共抽象部分类BaseForm:tenty:class,ienty的形式
{
关闭时受保护的覆盖无效(CancelEventArgs e)
{
//我不会被叫的
如果(EditMode==EditModes.Editable)
{
显示(这是“请提交或中止您的更改”);
e、 取消=真;
}
基数(e);
}
}
您可以尝试以下方法:

form1.Closing += delegate 
{
  // your logic
};

我一直在努力,找到了解决办法

if (_currentForm != null && !_currentForm.IsDisposed)
{
    // This call prevents calling the closing event -> _currentForm.Hide();
    _currentForm.Close();
}

这是Windows窗体。\uu.

这是一种错误行为,因为本机Windows MDI实现不支持隐藏MDI子窗口。Winforms使用了一个技巧来仍然支持Hide(),它实际上会破坏本机窗口,并在再次调用Show()时重新创建它。这有一个副作用,但是,Close()调用不再引发FormClosing/Closed事件,因为本机窗口已被Hide()调用破坏。这是一个bug,在Winforms中并不少见


解决方法很简单,调用Close()时不需要Hide(),只需删除它。

这篇文章对我也很有用,尽管我的情况略有不同

在这种情况下,避免
\u currentForm.Hide()工作正常,因为代码执行表单切换。
我发现问题也源于一个MDIChild,该MDIChild被位于顶部的另一个MDIChild隐藏

在这种情况下,基于总是调用
Dispose
这一事实,这里有一个解决方法也可以使用

可以这样做:

public abstract class FormExtenderClass : Form{
    private bool formClosingFired = false;
    private bool formClosedFired = false;

    protected override void OnFormClosing(FormClosingEventArgs e) {
        base.OnFormClosing(e);
        formClosingFired = !e.Cancel;
    }

    protected override void OnFormClosed(FormClosedEventArgs e) {
        base.OnFormClosed(e);
        formClosingFired = true;
    }

    protected override void Dispose(bool disposing) {
        if (!formClosingFired) OnFormClosing(new FormClosingEventArgs(CloseReason.UserClosing, false));
        if (!formClosedFired) OnFormClosed(new FormClosedEventArgs(CloseReason.UserClosing));
        base.Dispose(disposing);
    }
}
然后在MDIChildren的代码中,只需将第一行从

public partial class AutoForm : Form {


考虑到这在任何情况下都是一只狼狗。主要的区别是set
e.Cancel=true
在从Disposed as backup调用
FormClosing
的情况下无效。

有人能告诉我为什么会这样吗?这是很久以前的事了,但这篇文章救了我的命。非常感谢。