处理新表格的正确方法

本文关键字:方法 表格 新表格 处理 | 更新日期: 2023-09-27 18:07:12

所以在我的应用程序中,我倾向于在飞行中创建新的表单实例,然后使用Form.Show()来显示它们(非模态)。

private void test_click(object sender, EventArgs e)
{
    var form = new myForm();
    form.Show();
}

但是,Code Cracker告诉我应该处理这些表单。因此,我用"using"语句包装它们,但是它们在打开后立即关闭。

using (var form = new myForm())
{
    form.Show();
}

我不想使用Form.ShowDialog(),因为在一些情况下,我打开的新窗口只显示报告;我不需要它们是模态的。

处理新表格的正确方法

我需要在关闭表单后处置表单吗?

当您使用Show()显示表单时,您不需要处置它,因为它将在关闭后处置。但是当您使用ShowDialog()显示表单时,您需要处理表单,因为关闭后表单不会被处理。

当您关闭Form时,WM_CLOSE消息将被发送到窗口。如果您查看处理WM_CLOSE消息的WmClose方法的源代码,您将看到:

  • 对于模态表单(您使用ShowDialog显示),Dispose方法将不会被调用,窗体关闭后存在,您可以使用其属性来获取一些数据,或者您可以再次显示它。

  • 对于非模态表单(您使用Show展示的),在窗体关闭后,将调用Dispose方法。

所以结论是:

  • 当你使用Show方法显示表单时,你不需要(也不能)调用Dispose。表格关闭后自行处理

  • 当您使用ShowDialog显示表单时,您需要手动调用Dispose。一个好的做法是在using块中使用模态表单。

要显示模态对话框,最好使用using块:

//form will be disposed after the using block
using (var f = new MyForm())
{
    if (f.ShowDialog() == DialogResult.OK)
    {
        //Your logic to handle OK here
    }
}

对于非模态对话框,显示和忽略它:

var f = new MyForm();
f.Show();

嗯,"代码破解者"似乎是一个非常适合这个工具的术语,它的建议肯定会让您编写破坏程序的代码。黄金法则是永远不要相信静态代码分析工具的建议,他们都没有对代码的执行有足够的了解。它们永远无法知道哪个Dispose()调用完成了任务。

它看不到的是Form类已经知道如何处置自己。它很容易做到这一点,当窗口关闭时,对象变得不可用。当没有更多的窗口时,就没有理由继续使用Form对象。这种奢侈在。net中并不常见,但肯定是受到45年前为施乐工作的非常聪明的程序员的启发。

只有一个特殊的规则你必须记住,当你使用ShowDialog()来显示窗口时,它不会处理它自己。这是故意的,它使检索对话框结果的风险太大。使用 Using 语句来调用ShowDialog()是很容易做到的,调用不会返回,直到窗口关闭。

你可以实现某种形式的表单管理器,将订阅OnFormClosedEvent为它显示的每个表单,然后它可以处理它们…比如:

public class FormManager
{
    public T ShowForm<T>()
        where T : Form, new()
    {
        var t = new T();
        t.OnFormClosing += DisposeForm;
        return t;
    }
    void DisposeForm(object sender, FormClosedEventArgs args)
    {
        ((Form)sender).Dispose();
    }
}

您甚至可以实现IDisposable,并在处置管理器时处置所有未处置的窗体:)

所以根据MSDN的答案,当你关闭非模态表单时,它们会自动被丢弃。

我决定通过多次打开测试表单并关闭它们来测试这一点。我甚至同时打开了多个实例。一两秒钟后,这些表单使用的内存被回收,这表明它们被正确地处理了。