簡體   English   中英

FormClosing事件未調用MDI子表單

[英]FormClosing Event not called for MDI Child Form

我打算在打開一個新的時候關閉一個公式。 關閉公式時,我想在結束事件中處理一些特殊邏輯。 但是,在FormClosing和Closing事件中,也不在抽象基類中,也不在給定的手動附加事件form_FormClosing事件。

當我通過單擊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
}

抽象通用mdi子形式:

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);
    }
 }

這是行為不端,因為本機Windows MDI實現不支持隱藏MDI子窗口。 Winforms使用技巧仍然支持Hide(),它實際上會破壞本機窗口並在再次調用Show()時重新創建它。 這有副作用,但是Close()調用不再引發FormClosing / Closed事件,因為Native()調用已經破壞了本機窗口。 這是一個bug,在Winforms中並不罕見。

解決方法很簡單,當您調用Close()時不需要Hide(),只需將其刪除即可。

好吧,我一直在戰斗,找到了解決方案

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

這是Windows Forms ._。

這篇文章對我也很有用,雖然我的情況略有不同。

在這種情況下避免_currentForm.Hide(); 工作正常,因為代碼執行表單切換。 我發現問題也源於一個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 {

public partial class AutoForm : FormExtenderClass {

考慮到在任何情況下都是一個worarkound。 主要區別在於,在從Disposed作為備份調用FormClosing的情況下,set e.Cancel=true將不起作用。

你可以試試這個:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM