处理新表格的正确方法
本文关键字:方法 表格 新表格 处理 | 更新日期: 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的答案,当你关闭非模态表单时,它们会自动被丢弃。
我决定通过多次打开测试表单并关闭它们来测试这一点。我甚至同时打开了多个实例。一两秒钟后,这些表单使用的内存被回收,这表明它们被正确地处理了。