关闭时保持对话框窗体不卸载

Keep dialog form from unloading when closed

我有一个对话框 window,其中的列表框包含超过 3000 个项目,初始加载需要很长时间。为了加载这个对话框,我创建了一个实例 var dlg = new frmDlg(); 然后当我需要这个对话框时,我用 dlg.ShowDialog(this); 打开它 虽然这减少了列表框需要初始化的次数,但仍然需要很长时间对话框关闭后从内存中卸载对话框时显示表单的时间,需要重新加载视觉元素。有什么办法可以防止这种情况发生吗?对于正常形式,我只是隐藏 window 而不是关闭它,但这似乎不适用于对话框 windows.

将以下成员添加到frmDlg

private bool keepHandle;

protected override void OnFormClosing(FormClosingEventArgs e)
{
    keepHandle = e.CloseReason == CloseReason.UserClosing;
    base.OnFormClosing(e);
}

protected override void DestroyHandle()
{
    if (!keepHandle)
        base.DestroyHandle();
}

这应该可以防止对话框句柄在用户关闭对话框时被破坏。

表格 1:

public partial class Form1 : Form
{
    private Form2 reusable = null;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (reusable == null) reusable = new Form2();

        reusable.ShowDialog(this);
        switch (reusable.DialogResult)
        {
            case DialogResult.OK: MessageBox.Show("Ok clicked."); break;
            case DialogResult.Cancel: MessageBox.Show("Cancel clicked."); break;
            case DialogResult.None: MessageBox.Show("Form Closed."); break;
        }
    }
}

表格 2:

public partial class Form2 : Form
{
    private DialogResult dialogResult = DialogResult.None;
    public new DialogResult DialogResult
    {
        get => this.dialogResult;
        set => this.dialogResult = value;
    }

    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_Shown(object sender, EventArgs e)
    {
        this.dialogResult = DialogResult.None;
    }

    private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
        this.Hide();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.dialogResult = DialogResult.OK;
        this.Close();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        this.dialogResult = DialogResult.Cancel;
        this.Close();
    }
}

^ 几个注意事项:您不能再使用 ShowDialog 结果的结果,您需要创建自己的 DialogResult 属性,或者只使用完全不同的/新的 属性 来表示如何你的对话框被隐藏了。

您也不能再在任何按钮上使用 Button.DialogResult 属性,您需要实现自己的按钮单击事件来处理设置对话框结果。

这都是因为调用 ShowDialog 结果时 .net 框架中发生的事情。

此外,Dmitry 关于使用 e.CloseReason 的示例也有效 - 您可能希望允许关闭应用程序关闭之类的东西。这样您还可以处理 FormClosed 事件并在应用程序关闭之前执行任何您需要执行的快速清理。