0

我有一个可以打开子表单的表单(带有ShowDialog)。我想确保在主表单完成后正确处理子表单。我尝试将子表单添加到components主表单的成员中,但此时我得到了一个ArgumentNullException.
我知道我可以实例化components我自己,但这不是有点危险吗?有一天,我将在设计器视图中添加一个组件,这将new Container()在 Designer.cs 文件中生成该行,我永远不会知道我有两个组件实例在堆周围运行。
是否有更简单的方法来确保正在处理子表单?

编辑 - 将我的解决方案移至答案

4

4 回答 4

3

如果您在 showdialog 中使用该表格,您可能会认为在收到结果后您可以在那里处理该表格?

using(MyDialog dlg = new MyDialog())
{
   result = dlg.ShowDialog();
}
于 2009-06-01T07:39:51.653 回答
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;
        }
    }

保留子表单列表并将以下行添加到主表单的构造函数中:

Disposer.Register(ref this.components, this.MyDisposeAction);

当您的主窗体被释放时,您的所有子窗体也将被释放,例如:

private void MyDisposeAction(bool disposing)
{
  if (disposing)
  {
    foreach (var subForm in this.subForms)
    {
      subForm.Dispose(disposing);
    }
  } 
}
于 2009-06-01T10:02:26.563 回答
0

根据MSDN,通过调用的模态表单ShowDialog()不会自动处理,开发人员有责任处理它们:

当窗体显示为模式对话框时,单击关闭按钮(窗体右上角带有 X 的按钮)会导致窗体隐藏并且 DialogResult 属性设置为 DialogResult.Cancel。与无模式表单不同,当用户单击对话框的关闭表单按钮或设置 DialogResult 属性的值时,.NET Framework 不会调用 Close 方法。相反,该表单被隐藏并且可以再次显示而无需创建对话框的新实例。因为显示为对话框的表单没有关闭,所以当您的应用程序不再需要该表单时,您必须调用该表单的 Dispose 方法。

这里的相关点是“不再需要表格时”。在您的情况下,您似乎需要后续操作的表单,因此将ShowDialog()调用包装在using构造中不会达到目的。

我的建议是在 Main 表单的 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);
}
于 2009-06-01T09:15:10.510 回答
0

My current workaround:
I've added the Components property to the form, and am using it to access the collection

private IContainer Components{    get { return components ?? (components = new Container());}}
于 2009-06-29T06:21:10.217 回答