我有一个可以打开子表单的表单(ShowDialog
)。我想确保在完成主表单时正确处理子表单。
我尝试将子表单添加到主表单的components
成员中,但此刻我得到了ArgumentNullException
。
我知道我可以自己实例化components
,但这有点危险吗?有一天,我将在设计器视图中添加一个组件,这将在designer.cs文件中生成new Container()
行,我永远不会知道我有两个组件实例在堆中运行。
有没有更简单的方法来确保子表格被处理?
编辑 - 将我的解决方案移至答案
答案 0 :(得分:3)
如果您在showdialog中使用该表单,可以假设在收到结果后您可以在那里处理该表单吗?
using(MyDialog dlg = new MyDialog())
{
result = dlg.ShowDialog();
}
答案 1 :(得分:1)
您通常无法覆盖表单的Dipose方法,因为它已在Form.Designer.cs文件中定义。如何将自己的处置逻辑添加到表单中有一个小技巧。
使用以下课程:
public class Disposer : Component
{
private readonly Action<bool> disposeAction;
public Disposer(Action<bool> disposeAction)
{
this.disposeAction = disposeAction;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.disposeAction(disposing);
}
public static Disposer Register(ref IContainer container, Action<bool> disposeAction)
{
Disposer disposer = new Disposer(disposeAction);
if (container == null)
container = new System.ComponentModel.Container();
container.Add(disposer);
return disposer;
}
}
保留一个子表单列表,并将以下行添加到mainform的构造函数中:
Disposer.Register(ref this.components, this.MyDisposeAction);
当您的主要形式被处置时,您的所有子形态也将被处置,例如:
private void MyDisposeAction(bool disposing)
{
if (disposing)
{
foreach (var subForm in this.subForms)
{
subForm.Dispose(disposing);
}
}
}
答案 2 :(得分:0)
根据MSDN,通过ShowDialog()
调用的模态表单不会自动处理,开发人员有责任处置它们:
当窗体显示为模式对话框时,单击“关闭”按钮(窗体右上角带有X的按钮)会导致隐藏窗体并将DialogResult属性设置为DialogResult。取消。与无模式窗体不同,当用户单击对话框的关闭窗体按钮或设置DialogResult属性的值时,.NET Framework不会调用Close方法。而是隐藏表单,并且可以在不创建对话框的新实例的情况下再次显示该表单。因为显示为对话框的表单未关闭,所以当应用程序不再需要该表单时,必须调用表单的Dispose方法。
这里的相关点是“当不再需要表格时”。在您的情况下,您似乎需要用于后续操作的表单,因此将ShowDialog()
调用包装在using
构造中将无法实现此目的。
我的建议是在主表单的Dispose方法中处理Dialog,或者尽早处理:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
// dlg is a variable of type Form2(the dialog)
if (dlg != null)
{
dlg.Dispose();
dlg = null;
}
base.Dispose(disposing);
}
答案 3 :(得分:0)
我目前的解决方法:
我已将Components属性添加到表单中,并使用它来访问集合
private IContainer Components{ get { return components ?? (components = new Container());}}